diff --git a/README.md b/README.md index ed4ca39..90c9651 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ dfx start --background dfx deploy ``` -Once the job completes, your application will be available at `http://localhost:8000?canisterId={asset_canister_id}`. +Once the job completes, your application will be available at `http://localhost:8030?canisterId={asset_canister_id}`. Additionally, if you are making frontend changes, you can start a development server with diff --git a/dfx.json b/dfx.json index e86aa5b..bc052ba 100644 --- a/dfx.json +++ b/dfx.json @@ -3,6 +3,19 @@ "small_nft": { "main": "src/small_nft/main.mo", "type": "motoko" + }, + "small_nft_assets": { + "dependencies": [ + "small_nft" + ], + "frontend": { + "entrypoint": "src/small_nft_assets/src/index.html" + }, + "source": [ + "src/small_nft_assets/assets", + "dist/small_nft_assets/" + ], + "type": "assets" } }, "defaults": { @@ -14,7 +27,7 @@ "dfx": "0.8.1", "networks": { "local": { - "bind": "127.0.0.1:8000", + "bind": "127.0.0.1:8030", "type": "ephemeral" } }, diff --git a/package-lock.json b/package-lock.json index ba8c5c2..8f81c19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,8 +21,8 @@ "terser-webpack-plugin": "5.1.1", "util": "0.12.3", "webpack": "5.24.4", - "webpack-cli": "4.5.0", - "webpack-dev-server": "^3.11.2" + "webpack-cli": "^4.9.0", + "webpack-dev-server": "^3.11.3" } }, "node_modules/@dfinity/agent": { @@ -375,15 +375,6 @@ "ajv": "^6.9.1" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -1386,9 +1377,9 @@ "dev": true }, "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, "node_modules/commander": { @@ -2036,18 +2027,6 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -6752,18 +6731,17 @@ } }, "node_modules/webpack-cli": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.5.0.tgz", - "integrity": "sha512-wXg/ef6Ibstl2f50mnkcHblRPN/P9J4Nlod5Hg9HGFgSeF8rsqDGHJeVe4aR26q9l62TUJi6vmvC2Qz96YJw1Q==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.0.tgz", + "integrity": "sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.1", - "@webpack-cli/info": "^1.2.2", - "@webpack-cli/serve": "^1.3.0", - "colorette": "^1.2.1", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", "commander": "^7.0.0", - "enquirer": "^2.3.6", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", @@ -6785,9 +6763,6 @@ "@webpack-cli/generators": { "optional": true }, - "@webpack-cli/init": { - "optional": true - }, "@webpack-cli/migrate": { "optional": true }, @@ -7695,12 +7670,6 @@ "dev": true, "requires": {} }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -8490,9 +8459,9 @@ "dev": true }, "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, "commander": { @@ -9007,15 +8976,6 @@ "tapable": "^2.2.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -12704,18 +12664,17 @@ } }, "webpack-cli": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.5.0.tgz", - "integrity": "sha512-wXg/ef6Ibstl2f50mnkcHblRPN/P9J4Nlod5Hg9HGFgSeF8rsqDGHJeVe4aR26q9l62TUJi6vmvC2Qz96YJw1Q==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.0.tgz", + "integrity": "sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.1", - "@webpack-cli/info": "^1.2.2", - "@webpack-cli/serve": "^1.3.0", - "colorette": "^1.2.1", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", "commander": "^7.0.0", - "enquirer": "^2.3.6", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", diff --git a/package.json b/package.json index c47a47d..b4f8f05 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,12 @@ "name": "small_nft_assets", "version": "0.1.0", "description": "Internet Computer starter application", - "keywords": ["Internet Computer", "Motoko", "JavaScript", "Canister"], + "keywords": [ + "Internet Computer", + "Motoko", + "JavaScript", + "Canister" + ], "scripts": { "build": "webpack", "prebuild": "npm run copy:types", @@ -23,9 +28,9 @@ "stream-browserify": "3.0.0", "terser-webpack-plugin": "5.1.1", "util": "0.12.3", - "webpack-cli": "4.5.0", - "webpack-dev-server": "^3.11.2", - "webpack": "5.24.4" + "webpack": "5.24.4", + "webpack-cli": "^4.9.0", + "webpack-dev-server": "^3.11.3" }, "browserslist": [ "last 2 chrome version", diff --git a/src/small_nft/main.mo b/src/small_nft/main.mo index 3782cdd..e5ab86b 100644 --- a/src/small_nft/main.mo +++ b/src/small_nft/main.mo @@ -14,6 +14,8 @@ import Nat "mo:base/Nat"; // HashMapの第2引数で使用 import Hash "mo:base/Hash"; // HashMapの第3引数で使用 import Iter "mo:base/Iter"; // preupgrade,postupgradeで使う.HashMapのエントリを書き出す. + // エラー処理用のモジュール(add:by hokosugi) +import Result "mo:base/Result"; // `shared(<変数名>)`を加えることで,ICProtocolからこのトランザクションの呼び出し人を受け取ることができる. // `<変数名>.caller`でそのPrincipalを参照できる. @@ -57,6 +59,18 @@ shared(installer) actor class Small_NFT() { private var _tokenRegistry = HashMap.HashMap(1, Nat.equal, Hash.hash); private stable var _latestTokenID: Nat = 0; + //④ エラー処理(add: by hokosugi) + // Resultライブラリから型指定(https://smartcontracts.org/docs/base-libraries/Result.html) + public type Errors = { + #notFoundTokenInfo; + #alreadyExist; // 未使用 + }; + // okの時で関数内で別の型がある時に使う. + public type Okays = { + #canTransfer : Text; + #IsSuccess : Nat; + }; + public shared(msg) func mint(to : Principal, metadata : ?TokenMetadata) : async TokenID{ // 最新のtokeIDの更新 @@ -75,7 +89,8 @@ shared(installer) actor class Small_NFT() { return _latestTokenID; }; - public query func ownerOf(tokenId : TokenID) : async Text { //public funcの戻り値はasync型として記述 + + public query func ownerOf(tokenId : TokenID) : async Result.Result { //public funcの戻り値はasync型として記述 // このswitch-case文がmotokoの鬼門 /* HashMapはnull許容型として帰ってくるため,型安全性のため一度Nullを場合分けしなくてはならない. @@ -86,33 +101,33 @@ shared(installer) actor class Small_NFT() { switch(_tokenRegistry.get(tokenId)) { case(?tokenInfo) { //owner - return Principal.toText(tokenInfo.owner); + return #ok(Principal.toText(tokenInfo.owner)); }; case(_){ - return "none"; + return #err(#notFoundTokenInfo); }; }; }; - public shared(msg) func transfer(to : Principal, tokenId : TokenID) : async TokenID { + public shared(msg) func transfer(to : Principal, tokenId : TokenID) : async Result.Result { switch(_tokenRegistry.get(tokenId)) { case(?tokenInfo) { if(tokenInfo.owner != msg.caller ) { - return 0; + return #ok(#canTransfer("yes")); }; //ownerの書き換え tokenInfo.owner := to; // switch-caseは参照渡しなので,これで直接代入できるはず. - return tokenId; + return #ok(#IsSuccess(tokenId)); }; case(_){ - return 0; + return #err(#notFoundTokenInfo); }; }; }; - public query func latestTokenID() : async TokenID { - return _latestTokenID; + public query func latestTokenID() : async Result.Result { + return #ok(_latestTokenID); }; //State functions