일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- TOEFL
- 퀀트
- it
- 파이썬
- backtest
- 아마존 웹 서비스
- python
- 토플 라이팅
- AWS
- 암호화폐
- AUTOSAR
- 확률
- 백테스트
- Cloud
- 클라우드
- probability
- backtrader
- 백트레이더
- 프로그래밍
- 블록체인
- can
- 자동매매
- GeorgiaTech
- 오토사
- 토플
- 자동차sw
- toefl writing
- 개발자
- 비트코인
- Bitcoin
- Today
- Total
Leo's Garage
Smart Contract 개발 환경 구축 본문
Truffle : Solidity 개발 환경 - 배포, 테스트 등등
Ganache : Ethereum Blockchain Local 환경
https://github.com/DonationMarketNFT/SmartContractForBapp
git repository clone 후 아래 명령어 입력
$ npm install
$ cd node_modules/truffle
$ npm install solc@0.5.6
$ cd -
$ ln -s node_modules/truffle/build/cli.bundled.js truffle
$ export PATH=`pwd`:$PATH
위와 같이 하시면 Truffle 환경은 구성이 끝나게 됩니다.
Truffle로 바로 BaoBob 이나 cypress server로 배포할 수 있지만, 우선 저희는 SmartContract를 Test하고 검증해야 하기 때문에 Ganache를 이용하여 로컬 환경에서 배포하도록 하겠습니다.
Truffle과 Ganache 연동
아래 링크에서 Ganache를 설치하고 실행합니다.
https://trufflesuite.com/ganache/
Ganache를 실행하면 아래와 같은 Network ID와 RPC Server 정보가 있습니다.
보시면 Network ID는 1337이고 RPC Server는 HTTP://127.0.0.1 Port는 7545 입니다.
혹시 위와 설정이 다르다면, 가장 오른쪽 톱니바퀴를 누르시고 아래 화면에서 변경해주세요.
위와 같이 설정 후에 truffle-config.js를 아래와 같이 변경해줍니다.
// truffle-config.js
module.exports = {
networks: {
klaytn: {
host: "127.0.0.1", // rpc 주소
port: 7545, // port name
//from: "0x75a59b94889a05c03c66c3c84e9d2f8308ca4abd", // 현재는 테스트이기 때문에 필요없지만 추후 배포시에는 account 주소 입력 필요
network_id: "1337", // 로컬 네트워크 id -> 추후에 메인넷으로 변경 후 배포
//gas: 20000000, // 트랜잭션 가스 한도
//gasPrice: 25000000000, // Baobab의 gasPrice는 25 Gpeb입니다
},
},
compilers: {
solc: {
version: "0.5.6", // 컴파일러 버전을 0.5.6로 지정
},
},
};
Smart Contract 배포하기
우선 배포하고자 하는 Smart Contract를 contracts 폴더 내에 작성합니다.
그 이후에 migrations/1_initial_migraion.js에서 아래와 같이 작성해줍니다.
const Migrations = artifacts.require("./Migrations.sol");
const KlaytnGreeter = artifacts.require("./KlaytnGreeter.sol"); // 작성한 smart contract
module.exports = function (deployer) {
deployer.deploy(Migrations);
deployer.deploy(KlaytnGreeter, "Hello, Klaytn"); // 이와 같이 작성해주자
};
위와 같이 하나의 migration js file에 넣어도 되고, 혹은 migrations 폴더 내에 prefix 숫자를 넣어서 2_klaytn_greeter.js 와 같이 폴더를 생성하여 별도로 배포 코드를 작성해도 됩니다.
배포 전의 Ganache를 살펴보면 아래와 같습니다.
총 10개의 지갑이 있고 각각 100이더씩 있는 것을 볼 수 있습니다.
위와 같이 블록도 0개이고 Transaction도 없습니다.
이제 terminal에 아래와 같이 명령어를 넣어봅시다.
truffle migrate --network klaytn// klaytn은 truffle-config.js에서 설정한 network name이다.
⚡ ⚙ root@gimdaun-ui-MacBook-Pro ~/klaytn main ● truffle migrate --network klaytn
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'klaytn'
> Network id: 1337
> Block gas limit: 0x6691b7
1_initial_migration.js
======================
Replacing 'Migrations'
----------------------
> transaction hash: 0x06b66a084e478939099f01725186bb065e12e56415fe2f4a49d6df47506b199c
> Blocks: 0 Seconds: 0
> contract address: 0x6133DA5EB2d6Fb4CBb208D7788491212651BbBa6
> block number: 1
> block timestamp: 1644563019
> account: 0x111CF6AD702092D6D6103F8d18f41006A869A335
> balance: 99.99619978
> gas used: 190011
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00380022 ETH
Replacing 'KlaytnGreeter'
-------------------------
> transaction hash: 0xad84658fe1919822cac7b5c270bfefca8a5d376a8aa5f7941e7be070cd670f21
> Blocks: 0 Seconds: 0
> contract address: 0x4FB897FFe54D903ccBd2DE14765A948Bca5235Df
> block number: 2
> block timestamp: 1644563019
> account: 0x111CF6AD702092D6D6103F8d18f41006A869A335
> balance: 99.9917825
> gas used: 220864
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00441728 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0082175 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.0082175 ETH
위와 같이 log가 나오면서 로컬 환경에 배포가 됨을 알 수 있습니다.
이제 Ganache에 가서 확인해보면
위와 같이 smart contract 배포로 인해 Gas가 사용되어 이더가 소모된 부분과 블록이 쌓인 부분, transaction이 발생한 부분을 모니터링 할 수 있습니다.
smart contract의 동작만을 검증하기 때문에 이더리움 로컬 네트워크 상에서 진행해도 문제 없을 것을 판단됩니다.
truffle console 사용하기
정상적으로 서버에 Smart Contract가 배포가 되었다면, truffle console을 이용하여 배포된 smart cotract내에 함수나 변수를 확인할 수 있습니다.
$ truffle console
배포가 정상적으로 된 상태에서 상기 명령어를 치면 아래처럼 terminal 창이 변경됩니다.
$ truffle console
truffle(ganache)>
이제 여기서 아래와 같이 입력하면
truffle(ganache)> NFTSimple.deployed().then(function(instance){it=instance})
undefined
undefined라는 msg가 나오게 되는데 it라는 변수에 NFTSimple smartcontract instance가 들어오게 됩니다.
이 때 Console창에 아래와 같이 입력하면
truffle(ganache)> it
TruffleContract {
constructor: [Function: TruffleContract] {
_constructorMethods: {
setProvider: [Function: setProvider],
new: [Function: new],
at: [AsyncFunction: at],
deployed: [AsyncFunction: deployed],
defaults: [Function: defaults],
hasNetwork: [Function: hasNetwork],
isDeployed: [Function: isDeployed],
detectNetwork: [AsyncFunction: detectNetwork],
setNetwork: [Function: setNetwork],
setNetworkType: [Function: setNetworkType],
setWallet: [Function: setWallet],
resetAddress: [Function: resetAddress],
link: [Function: link],
clone: [Function: clone],
addProp: [Function: addProp],
toJSON: [Function: toJSON],
decodeLogs: [Function: decodeLogs]
},
_properties: {
contract_name: [Object],
contractName: [Object],
gasMultiplier: [Object],
timeoutBlocks: [Object],
autoGas: [Object],
numberFormat: [Object],
abi: [Object],
metadata: [Function: metadata],
network: [Function: network],
networks: [Function: networks],
address: [Object],
transactionHash: [Object],
links: [Function: links],
events: [Function: events],
binary: [Function: binary],
deployedBinary: [Function: deployedBinary],
unlinked_binary: [Object],
bytecode: [Object],
deployedBytecode: [Object],
sourceMap: [Object],
deployedSourceMap: [Object],
source: [Object],
sourcePath: [Object],
legacyAST: [Object],
ast: [Object],
compiler: [Object],
schema_version: [Function: schema_version],
schemaVersion: [Function: schemaVersion],
updated_at: [Function: updated_at],
updatedAt: [Function: updatedAt],
userdoc: [Function: userdoc],
devdoc: [Function: devdoc]
},
_property_values: {},
_json: {
contractName: 'NFTSimple',
abi: [Array],
metadata: '{"compiler":{"version":"0.5.6+commit.b259423e"},"language":"Solidity","output":{"abi":[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"tokenURI","type":"string"}],"name":"mintWithTokenURI","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"uri","type":"string"}],"name":"setTokenUri","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenURIs","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"ownedTokens","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"balance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"/Users/kimdawoon/klaytn/contracts/NFTSimple.sol":"NFTSimple"},"evmVersion":"petersburg","libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"/Users/kimdawoon/klaytn/contracts/NFTSimple.sol":{"keccak256":"0xf0f74d9232e794b5b9043885d7543ad446f4659cc06cdff5ee1da3886e757d83","urls":["bzzr://ce577591ab3e9d25d63f467e272aff539b0b535cfc78e93ce807eb6d2518a57b"]}},"version":1}',
bytecode: '0x60806040526040518060400160405280600881526020017f4b6c61794c696f6e0000000000000000000000000000000000000000000000008152506000908051906020019062000051929190620000b4565b506040518060400160405280600281526020017f4b4c000000000000000000000000000000000000000000000000000000000000815250600190805190602001906200009f929190620000b4565b50348015620000ad57600080fd5b5062000163565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620000f757805160ff191683800117855562000128565b8280016001018555821562000128579182015b82811115620001275782518255916020019190600101906200010a565b5b5090506200013791906200013b565b5090565b6200016091905b808211156200015c57600081600090555060010162000142565b5090565b90565b6114b380620001736000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c806370a082311161006657806370a08231146103fd57806395d89b4114610455578063b12ab40f146104d8578063b88d4fde14610571578063e3d670d7146106765761009e565b806306fdde03146100a35780631caaa4871461012657806350bb4e7f1461019457806357f7789e146102915780636c8b703f14610356575b600080fd5b6100ab6106ce565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100eb5780820151818401526020810190506100d0565b50505050905090810190601f1680156101185780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101526004803603602081101561013c57600080fd5b810190808035906020019092919050505061076c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610277600480360360608110156101aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156101f157600080fd5b82018360208201111561020357600080fd5b8035906020019184600183028401116401000000008311171561022557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061079f565b604051808215151515815260200191505060405180910390f35b610354600480360360408110156102a757600080fd5b8101908080359060200190929190803590602001906401000000008111156102ce57600080fd5b8201836020820111156102e057600080fd5b8035906020019184600183028401116401000000008311171561030257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061088f565b005b6103826004803603602081101561036c57600080fd5b81019080803590602001909291905050506108bb565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c25780820151818401526020810190506103a7565b50505050905090810190601f1680156103ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61043f6004803603602081101561041357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061096b565b6040518082815260200191505060405180910390f35b61045d610a3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561049d578082015181840152602081019050610482565b50505050905090810190601f1680156104ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61051a600480360360208110156104ee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ada565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561055d578082015181840152602081019050610542565b505050509050019250505060405180910390f35b6106746004803603608081101561058757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105ee57600080fd5b82018360208201111561060057600080fd5b8035906020019184600183028401116401000000008311171561062257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610b71565b005b6106b86004803603602081101561068c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610df5565b6040518082815260200191505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107645780601f1061073957610100808354040283529160200191610764565b820191906000526020600020905b81548152906001019060200180831161074757829003601f168201915b505050505081565b60026020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000836002600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160036000858152602001908152602001600020908051906020019061081a92919061133d565b50600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020839080600181540180825580915050906001820390600052602060002001600090919290919091505550600190509392505050565b806003600084815260200190815260200160002090805190602001906108b692919061133d565b505050565b60036020528060005260406000206000915090508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109635780601f1061093857610100808354040283529160200191610963565b820191906000526020600020905b81548152906001019060200180831161094657829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061145f6029913960400191505060405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ad25780601f10610aa757610100808354040283529160200191610ad2565b820191906000526020600020905b815481529060010190602001808311610ab557829003601f168201915b505050505081565b6060600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610b6557602002820191906000526020600020905b815481526020019060010190808311610b51575b50505050509050919050565b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610c12576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f66726f6d20212d206d73672e73656e646572000000000000000000000000000081525060200191505060405180910390fd5b6002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610cc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061143d6022913960400191505060405180910390fd5b610cd38483610e07565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020829080600181540180825580915050906001820390600052602060002001600090919290919091505550826002600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610d9a8484848461106e565b610def576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061140f602e913960400191505060405180910390fd5b50505050565b6000610e008261096b565b9050919050565b60006001600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905003905060008090505b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081101561101557600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208181548110610eeb57fe5b906000526020600020015483141561100857600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610f4757fe5b9060005260206000200154600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610f9c57fe5b906000526020600020018190555082600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110610ff557fe5b9060005260206000200181905550611015565b8080600101915050610e57565b50600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548091906001900361106891906113bd565b50505050565b600080606061107c8661132a565b61108b57600192505050611322565b8573ffffffffffffffffffffffffffffffffffffffff16636745782b60e01b33898888604051602401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561115b578082015181840152602081019050611140565b50505050905090810190601f1680156111885780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061122057805182526020820191506020810190506020830392506111fd565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611282576040519150601f19603f3d011682016040523d82523d6000602084013e611287565b606091505b508092508193505050600081511415801561130b5750636745782b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168180602001905160208110156112d957600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b1561131b57600192505050611322565b6000925050505b949350505050565b600080823b905060008111915050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061137e57805160ff19168380011785556113ac565b828001600101855582156113ac579182015b828111156113ab578251825591602001919060010190611390565b5b5090506113b991906113e9565b5090565b8154818355818111156113e4578183600052602060002091820191016113e391906113e9565b5b505050565b61140b91905b808211156114075760008160009055506001016113ef565b5090565b9056fe4b495031373a207472616e7366657220746f206e6f6e204b49503137526563656976657220696d706c656d656e74796f7520617265206e6f7420746865206f776e6572206f662074686520746f6b656e4b495031373a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373a165627a7a7230582074631fbcf9d3afb7a18a7098f93ab03085fef6dcfc8608f48f7cc7585da581380029',
deployedBytecode: '0x608060405234801561001057600080fd5b506004361061009e5760003560e01c806370a082311161006657806370a08231146103fd57806395d89b4114610455578063b12ab40f146104d8578063b88d4fde14610571578063e3d670d7146106765761009e565b806306fdde03146100a35780631caaa4871461012657806350bb4e7f1461019457806357f7789e146102915780636c8b703f14610356575b600080fd5b6100ab6106ce565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100eb5780820151818401526020810190506100d0565b50505050905090810190601f1680156101185780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101526004803603602081101561013c57600080fd5b810190808035906020019092919050505061076c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610277600480360360608110156101aa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156101f157600080fd5b82018360208201111561020357600080fd5b8035906020019184600183028401116401000000008311171561022557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061079f565b604051808215151515815260200191505060405180910390f35b610354600480360360408110156102a757600080fd5b8101908080359060200190929190803590602001906401000000008111156102ce57600080fd5b8201836020820111156102e057600080fd5b8035906020019184600183028401116401000000008311171561030257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061088f565b005b6103826004803603602081101561036c57600080fd5b81019080803590602001909291905050506108bb565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c25780820151818401526020810190506103a7565b50505050905090810190601f1680156103ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61043f6004803603602081101561041357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061096b565b6040518082815260200191505060405180910390f35b61045d610a3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561049d578082015181840152602081019050610482565b50505050905090810190601f1680156104ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61051a600480360360208110156104ee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ada565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561055d578082015181840152602081019050610542565b505050509050019250505060405180910390f35b6106746004803603608081101561058757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105ee57600080fd5b82018360208201111561060057600080fd5b8035906020019184600183028401116401000000008311171561062257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610b71565b005b6106b86004803603602081101561068c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610df5565b6040518082815260200191505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107645780601f1061073957610100808354040283529160200191610764565b820191906000526020600020905b81548152906001019060200180831161074757829003601f168201915b505050505081565b60026020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000836002600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160036000858152602001908152602001600020908051906020019061081a92919061133d565b50600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020839080600181540180825580915050906001820390600052602060002001600090919290919091505550600190509392505050565b806003600084815260200190815260200160002090805190602001906108b692919061133d565b505050565b60036020528060005260406000206000915090508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109635780601f1061093857610100808354040283529160200191610963565b820191906000526020600020905b81548152906001019060200180831161094657829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061145f6029913960400191505060405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ad25780601f10610aa757610100808354040283529160200191610ad2565b820191906000526020600020905b815481529060010190602001808311610ab557829003601f168201915b505050505081565b6060600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610b6557602002820191906000526020600020905b815481526020019060010190808311610b51575b50505050509050919050565b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610c12576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f66726f6d20212d206d73672e73656e646572000000000000000000000000000081525060200191505060405180910390fd5b6002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610cc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061143d6022913960400191505060405180910390fd5b610cd38483610e07565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020829080600181540180825580915050906001820390600052602060002001600090919290919091505550826002600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610d9a8484848461106e565b610def576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061140f602e913960400191505060405180910390fd5b50505050565b6000610e008261096b565b9050919050565b60006001600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905003905060008090505b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081101561101557600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208181548110610eeb57fe5b906000526020600020015483141561100857600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610f4757fe5b9060005260206000200154600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610f9c57fe5b906000526020600020018190555082600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110610ff557fe5b9060005260206000200181905550611015565b8080600101915050610e57565b50600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548091906001900361106891906113bd565b50505050565b600080606061107c8661132a565b61108b57600192505050611322565b8573ffffffffffffffffffffffffffffffffffffffff16636745782b60e01b33898888604051602401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561115b578082015181840152602081019050611140565b50505050905090810190601f1680156111885780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061122057805182526020820191506020810190506020830392506111fd565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611282576040519150601f19603f3d011682016040523d82523d6000602084013e611287565b606091505b508092508193505050600081511415801561130b5750636745782b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168180602001905160208110156112d957600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b1561131b57600192505050611322565b6000925050505b949350505050565b600080823b905060008111915050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061137e57805160ff19168380011785556113ac565b828001600101855582156113ac579182015b828111156113ab578251825591602001919060010190611390565b5b5090506113b991906113e9565b5090565b8154818355818111156113e4578183600052602060002091820191016113e391906113e9565b5b505050565b61140b91905b808211156114075760008160009055506001016113ef565b5090565b9056fe4b495031373a207472616e7366657220746f206e6f6e204b49503137526563656976657220696d706c656d656e74796f7520617265206e6f7420746865206f776e6572206f662074686520746f6b656e4b495031373a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373a165627a7a7230582074631fbcf9d3afb7a18a7098f93ab03085fef6dcfc8608f48f7cc7585da581380029',
sourceMap: '85:4074:1:-;;;110:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;147:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;85:4074;8:9:-1;5:2;;;30:1;27;20:12;5:2;85:4074:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;',
deployedSourceMap: '85:4074:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;85:4074:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;110:31:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;192:45;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;192:45:1;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;659:375;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;659:375:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;659:375:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;659:375:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;659:375:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;659:375:1;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;3984:173;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;3984:173:1;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;3984:173:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;3984:173:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;3984:173:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;3984:173:1;;;;;;;;;;;;;;;:::i;:::-;;266:43;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;266:43:1;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;266:43:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1040:207;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1040:207:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;147:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;147:27:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3861:117;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;3861:117:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;3861:117:1;;;;;;;;;;;;;;;;;1358:772;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;1358:772:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;1358:772:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;1358:772:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;1358:772:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;1358:772:1;;;;;;;;;;;;;;;:::i;:::-;;1250:102;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1250:102:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;110:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;192:45::-;;;;;;;;;;;;;;;;;;;;;;:::o;659:375::-;753:4;890:2;868:10;:19;879:7;868:19;;;;;;;;;;;;:24;;;;;;;;;;;;;;;;;;923:8;902:9;:18;912:7;902:18;;;;;;;;;;;:29;;;;;;;;;;;;:::i;:::-;;975:12;:16;988:2;975:16;;;;;;;;;;;;;;;997:7;975:30;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;975:30:1;;;;;;;;;;;;;;;;;;;;;;1023:4;1016:11;;659:375;;;;;:::o;3984:173::-;4136:3;4120:9;:13;4130:2;4120:13;;;;;;;;;;;:19;;;;;;;;;;;;:::i;:::-;;3984:173;;:::o;266:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1040:207::-;1095:7;1144:1;1127:19;;:5;:19;;;;1110:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1218:12;:19;1231:5;1218:19;;;;;;;;;;;;;;;:26;;;;1211:33;;1040:207;;;:::o;147:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3861:117::-;3918:16;3952:12;:19;3965:5;3952:19;;;;;;;;;;;;;;;3945:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3861:117;;;:::o;1358:772::-;1479:10;1471:18;;:4;:18;;;1463:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1600:10;:19;1611:7;1600:19;;;;;;;;;;;;;;;;;;;;;1592:27;;:4;:27;;;1584:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1739:35;1760:4;1766:7;1739:20;:35::i;:::-;1784:12;:16;1797:2;1784:16;;;;;;;;;;;;;;;1806:7;1784:30;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;1784:30:1;;;;;;;;;;;;;;;;;;;;;;1857:2;1835:10;:19;1846:7;1835:19;;;;;;;;;;;;:24;;;;;;;;;;;;;;;;;;2006:47;2028:4;2034:2;2038:7;2047:5;2006:21;:47::i;:::-;1985:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1358:772;;;;:::o;1250:102::-;1303:4;1327:16;1337:5;1327:9;:16::i;:::-;1320:23;;1250:102;;;:::o;3216:639::-;3410:20;3461:1;3433:12;:18;3446:4;3433:18;;;;;;;;;;;;;;;:25;;;;:29;3410:52;;3476:9;3488:1;3476:13;;3472:340;3495:12;:18;3508:4;3495:18;;;;;;;;;;;;;;;:25;;;;3491:1;:29;3472:340;;;3554:12;:18;3567:4;3554:18;;;;;;;;;;;;;;;3573:1;3554:21;;;;;;;;;;;;;;;;3543:7;:32;3540:262;;;3673:12;:18;3686:4;3673:18;;;;;;;;;;;;;;;3692:12;3673:32;;;;;;;;;;;;;;;;3649:12;:18;3662:4;3649:18;;;;;;;;;;;;;;;3668:1;3649:21;;;;;;;;;;;;;;;:56;;;;3757:7;3722:12;:18;3735:4;3722:18;;;;;;;;;;;;;;;3741:12;3722:32;;;;;;;;;;;;;;;:42;;;;3782:5;;3540:262;3522:3;;;;;;;3472:340;;;;3821:12;:18;3834:4;3821:18;;;;;;;;;;;;;;;:27;;;;;;;;;;;;:::i;:::-;;3216:639;;;:::o;2182:856::-;2293:4;2308:12;2330:23;2368:14;2379:2;2368:10;:14::i;:::-;2364:94;;2443:4;2436:11;;;;;;2364:94;2492:2;:7;;512:10;2600:15;;2673:10;2701:4;2723:7;2748:5;2560:207;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;2560:207:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;2560:207:1;;;;;;;38:4:-1;29:7;25:18;67:10;61:17;96:58;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;2560:207:1;2492:285;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;2492:285:1;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;2468:309:1;;;;;;;;2824:1;2803:10;:17;:22;;:160;;;;;512:10;2948:15;;2912:51;;;2923:10;2912:32;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;2912:32:1;;;;;;;;;;;;;;;;:51;;;;2803:160;2787:223;;;2995:4;2988:11;;;;;;2787:223;3026:5;3019:12;;;;2182:856;;;;;;;:::o;3044:166::-;3103:4;3118:12;3170:7;3158:20;3150:28;;3202:1;3195:4;:8;3188:15;;;3044:166;;;:::o;85:4074::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o',
source: '//Klaytn IDE uses solidity 0.4.24 0.5.6 versions.\n' +
'pragma solidity >=0.4.24 <=0.5.6;\n' +
'\n' +
'contract NFTSimple {\n' +
' string public name = "KlayLion";\n' +
' string public symbol = "KL"; // 단위 \n' +
'\n' +
' mapping(uint256 => address) public tokenOwner; // token owner mapping\n' +
' mapping(uint256 => string) public tokenURIs; // key - value type declare\n' +
'\n' +
' // 소유한 토큰 리스트\n' +
' mapping(address => uint256[]) private _ownedTokens;\n' +
' // onKIP17Received bytes value\n' +
'\n' +
' bytes4 private constant _KIP17_RECEIVED = 0x6745782b;\n' +
'\n' +
' // mint(tokenId, uri, owner) : 발행\n' +
' // transferFrom(from, to, tokenId) : 전송 -> owner가 바뀌는 것 (from -> to)\n' +
'\n' +
' function mintWithTokenURI(address to, uint256 tokenId, string memory tokenURI) public returns(bool){\n' +
' // to에게 tokenId(일련번호)를 발행하겠다. \n' +
' // 적힐 글자는 tokenURI\n' +
' tokenOwner[tokenId] = to;\n' +
' tokenURIs[tokenId] = tokenURI;\n' +
'\n' +
' // add token to the list\n' +
' _ownedTokens[to].push(tokenId);\n' +
'\n' +
' return true;\n' +
' }\n' +
'\n' +
' function balanceOf(address owner) public view returns (uint256) {\n' +
' require(\n' +
' owner != address(0),\n' +
' "KIP17: balance query for the zero address"\n' +
' );\n' +
' return _ownedTokens[owner].length;\n' +
'}\n' +
'\n' +
' function balance (address _addr) public view returns(uint){\n' +
' return balanceOf(_addr);\n' +
' }\n' +
'\n' +
' function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public{\n' +
' require(from == msg.sender, "from !- msg.sender"); // 보내는 사람이 현재 이 함수를 실행한 주체 \n' +
' require(from == tokenOwner[tokenId], "you are not the owner of the token"); // 보내는 사람이 보내려고 하는 토큰의 주인\n' +
' //\n' +
' _removeTokenFromList(from, tokenId);\n' +
' _ownedTokens[to].push(tokenId);\n' +
' //\n' +
' tokenOwner[tokenId] = to;\n' +
'\n' +
' // 만약에 받는 쪽이 실행할 코드가 있는 스마트 컨트렉트이면 코드를 실행할 것\n' +
' require(\n' +
' _checkOnKIP17Received(from, to, tokenId, _data), "KIP17: transfer to non KIP17Receiver implement"\n' +
' );\n' +
'\n' +
' \n' +
' }\n' +
'\n' +
' //internal option : 외부 호춣 불가 \n' +
' function _checkOnKIP17Received(address from, address to, uint256 tokenId, bytes memory _data) internal returns(bool){\n' +
' bool success;\n' +
' bytes memory returndata;\n' +
'\n' +
' if(!isContract(to)){ // smart contract address인지 판별\n' +
' return true;\n' +
' }\n' +
'\n' +
' (success, returndata) = to.call( // 성공여부와 return 값을 받아와라 \n' +
' abi.encodeWithSelector(\n' +
' _KIP17_RECEIVED, //smart contract면 이걸 실행해라\n' +
' msg.sender,\n' +
' from,\n' +
' tokenId,\n' +
' _data\n' +
' )\n' +
' );\n' +
' if(\n' +
' returndata.length != 0 && //만약 return 값이 존재하며 그 값이 _KIP17_RECEIVED이면, \n' +
' abi.decode(returndata, (bytes4)) == _KIP17_RECEIVED\n' +
' ) {\n' +
' return true;\n' +
' }\n' +
' return false;\n' +
' }\n' +
'\n' +
' function isContract(address account) internal view returns(bool){\n' +
' uint256 size;\n' +
' assembly {size := extcodesize(account)}\n' +
' return size > 0;\n' +
' }\n' +
'\n' +
' function _removeTokenFromList(address from, uint256 tokenId) private{\n' +
' // [10, 15, 19, 20] -> 19번을 삭제하고 싶어요.\n' +
' // [10, 15, 20, 19]\n' +
' // [10, 15, 20]\n' +
' uint256 lastTokenIdx = _ownedTokens[from].length - 1;\n' +
' for(uint256 i = 0; i < _ownedTokens[from].length; i++){\n' +
' if(tokenId == _ownedTokens[from][i]){\n' +
' // swap last token with deleting token;\n' +
' _ownedTokens[from][i] = _ownedTokens[from][lastTokenIdx];\n' +
' _ownedTokens[from][lastTokenIdx] = tokenId;\n' +
' break;\n' +
' }\n' +
' }\n' +
' _ownedTokens[from].length--;\n' +
' }\n' +
'\n' +
' function ownedTokens(address owner) public view returns (uint256[] memory){\n' +
' return _ownedTokens[owner];\n' +
' }\n' +
'\n' +
' function setTokenUri(uint256 id, string memory uri) public { // memory는 좀 긴 타입의 데이터를 표시할 떄 쓴다. \n' +
' tokenURIs[id] = uri; // mapping\n' +
' }\n' +
'} \n' +
'\n' +
'\n' +
'contract NFTMarket {\n' +
' //token 보낸 사람을 기억 W\n' +
' mapping(uint256 => address) public seller;\n' +
'\n' +
' function buyNFT(uint256 tokenId, address NFTAddress) public payable returns (bool){ //payable이 있어야 KLAY를 보낼 수 있다. \n' +
' //NFTAddress에는 NFTSimple이 배포된 주소를 넣어준다. \n' +
'\n' +
' // 판매한 사람에게 0.01 KLAY 전송\n' +
' address payable receiver = address(uint160(seller[tokenId])); // 돈을 받을 사람은 seller이다. payable L 돈을 받을 수 있는~\n' +
'\n' +
' // Send 0.01 KAY to receiver\n' +
' // 10 ** 18 PEB = 1 KLAY\n' +
' // 10 ** 16 PEB = 0.01 KLAY\n' +
' receiver.transfer(10 ** 16); // buyNFT를 호출한 사람이 이것까지 낸다. \n' +
'\n' +
" NFTSimple(NFTAddress).safeTransferFrom(address(this), msg.sender, tokenId, '0x00'); // to 대신 msg.sender 무조건 이 함수 호출한 사람에게 보낸다. \n" +
' return true;\n' +
' }\n' +
'\n' +
' // Market이 토큰을 받았을 때 (판매대에 올라갔을 때), 판매자가 누구인지 기록해야 한다. \n' +
' function onKIP17Received(address operator, address from , uint256 tokenId, bytes memory data) public returns (bytes4) {\n' +
' seller[tokenId] = from;\n' +
'\n' +
' return bytes4(keccak256("onKIP17Received(address,address,uint256,bytes)"));\n' +
' // return이 의미하는 것은 현재 구현된 함수가 이 smart contract에 존재한다는 것을 알리는 용도\n' +
' }\n' +
'}',
sourcePath: '/Users/kimdawoon/klaytn/contracts/NFTSimple.sol',
ast: [Object],
legacyAST: [Object],
compiler: [Object],
networks: [Object],
schemaVersion: '3.0.14',
updatedAt: '2022-02-12T05:50:19.373Z',
devdoc: [Object],
userdoc: [Object]
},
setProvider: [Function: bound setProvider],
new: [Function: bound new] {
estimateGas: [Function: bound estimateDeployment]
},
at: [Function: bound at] AsyncFunction,
deployed: [Function: bound deployed] AsyncFunction,
defaults: [Function: bound defaults],
hasNetwork: [Function: bound hasNetwork],
isDeployed: [Function: bound isDeployed],
detectNetwork: [Function: bound detectNetwork] AsyncFunction,
setNetwork: [Function: bound setNetwork],
setNetworkType: [Function: bound setNetworkType],
setWallet: [Function: bound setWallet],
resetAddress: [Function: bound resetAddress],
link: [Function: bound link],
clone: [Function: bound clone],
addProp: [Function: bound addProp],
toJSON: [Function: bound toJSON],
decodeLogs: [Function: bound decodeLogs],
web3: Web3Shim {
currentProvider: [Getter/Setter],
_requestManager: [RequestManager],
givenProvider: null,
providers: [Object],
_provider: [HttpProvider],
setProvider: [Function (anonymous)],
BatchRequest: [Function: bound Batch],
extend: [Function],
version: '1.2.1',
utils: [Object],
eth: [Eth],
shh: [Shh],
bzz: [Bzz],
networkType: 'ethereum'
},
class_defaults: {
from: '0x2a467DA4a19ACac7D793381E0801b463d49a40D0',
gas: 6721975,
gasPrice: 20000000000
},
currentProvider: HttpProvider {
host: 'http://127.0.0.1:7545',
httpAgent: [Agent],
timeout: 0,
headers: undefined,
connected: true,
send: [Function (anonymous)],
_alreadyWrapped: true
},
network_id: '5777',
networkType: 'ethereum'
},
methods: {
'name()': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'tokenOwner(uint256)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'tokenURIs(uint256)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'symbol()': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'mintWithTokenURI(address,uint256,string)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'balanceOf(address)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'balance(address)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'safeTransferFrom(address,address,uint256,bytes)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'ownedTokens(address)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
'setTokenUri(uint256,string)': [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
}
},
abi: [
{
constant: true,
inputs: [],
name: 'name',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0x06fdde03'
},
{
constant: true,
inputs: [Array],
name: 'tokenOwner',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0x1caaa487'
},
{
constant: true,
inputs: [Array],
name: 'tokenURIs',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0x6c8b703f'
},
{
constant: true,
inputs: [],
name: 'symbol',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0x95d89b41'
},
{
constant: false,
inputs: [Array],
name: 'mintWithTokenURI',
outputs: [Array],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
signature: '0x50bb4e7f'
},
{
constant: true,
inputs: [Array],
name: 'balanceOf',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0x70a08231'
},
{
constant: true,
inputs: [Array],
name: 'balance',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0xe3d670d7'
},
{
constant: false,
inputs: [Array],
name: 'safeTransferFrom',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
signature: '0xb88d4fde'
},
{
constant: true,
inputs: [Array],
name: 'ownedTokens',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0xb12ab40f'
},
{
constant: false,
inputs: [Array],
name: 'setTokenUri',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
signature: '0x57f7789e'
}
],
address: '0xC4D4a60745bDc14Dd92aD40909A5D162CE77b803',
transactionHash: undefined,
contract: Contract {
currentProvider: [Getter/Setter],
_requestManager: RequestManager {
provider: [HttpProvider],
providers: [Object],
subscriptions: {}
},
givenProvider: null,
providers: {
WebsocketProvider: [Function: WebsocketProvider],
HttpProvider: [Function: HttpProvider],
IpcProvider: [Function: IpcProvider]
},
_provider: HttpProvider {
host: 'http://127.0.0.1:7545',
httpAgent: [Agent],
timeout: 0,
headers: undefined,
connected: true,
send: [Function (anonymous)],
_alreadyWrapped: true
},
setProvider: [Function (anonymous)],
BatchRequest: [Function: bound Batch],
extend: [Function: ex] {
formatters: [Object],
utils: [Object],
Method: [Function: Method]
},
clearSubscriptions: [Function (anonymous)],
options: { address: [Getter/Setter], jsonInterface: [Getter/Setter] },
defaultAccount: [Getter/Setter],
defaultBlock: [Getter/Setter],
methods: {
name: [Function: bound _createTxObject],
'0x06fdde03': [Function: bound _createTxObject],
'name()': [Function: bound _createTxObject],
tokenOwner: [Function: bound _createTxObject],
'0x1caaa487': [Function: bound _createTxObject],
'tokenOwner(uint256)': [Function: bound _createTxObject],
tokenURIs: [Function: bound _createTxObject],
'0x6c8b703f': [Function: bound _createTxObject],
'tokenURIs(uint256)': [Function: bound _createTxObject],
symbol: [Function: bound _createTxObject],
'0x95d89b41': [Function: bound _createTxObject],
'symbol()': [Function: bound _createTxObject],
mintWithTokenURI: [Function: bound _createTxObject],
'0x50bb4e7f': [Function: bound _createTxObject],
'mintWithTokenURI(address,uint256,string)': [Function: bound _createTxObject],
balanceOf: [Function: bound _createTxObject],
'0x70a08231': [Function: bound _createTxObject],
'balanceOf(address)': [Function: bound _createTxObject],
balance: [Function: bound _createTxObject],
'0xe3d670d7': [Function: bound _createTxObject],
'balance(address)': [Function: bound _createTxObject],
safeTransferFrom: [Function: bound _createTxObject],
'0xb88d4fde': [Function: bound _createTxObject],
'safeTransferFrom(address,address,uint256,bytes)': [Function: bound _createTxObject],
ownedTokens: [Function: bound _createTxObject],
'0xb12ab40f': [Function: bound _createTxObject],
'ownedTokens(address)': [Function: bound _createTxObject],
setTokenUri: [Function: bound _createTxObject],
'0x57f7789e': [Function: bound _createTxObject],
'setTokenUri(uint256,string)': [Function: bound _createTxObject]
},
events: { allEvents: [Function: bound ] },
_address: '0xC4D4a60745bDc14Dd92aD40909A5D162CE77b803',
_jsonInterface: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object]
]
},
name: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
tokenOwner: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
tokenURIs: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
symbol: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
mintWithTokenURI: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
balanceOf: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
balance: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
safeTransferFrom: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
ownedTokens: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
setTokenUri: [Function (anonymous)] {
call: [Function (anonymous)],
sendTransaction: [Function (anonymous)],
estimateGas: [Function (anonymous)],
request: [Function (anonymous)]
},
sendTransaction: [Function (anonymous)],
send: [Function (anonymous)],
allEvents: [Function (anonymous)],
getPastEvents: [Function (anonymous)]
}
각종 smart contract 관련 정보들이 나오게 됩니다.
또한 console에 it. tap을 두번 치게 되면
truffle(ganache)> it.
it.__proto__ it.hasOwnProperty it.isPrototypeOf
it.propertyIsEnumerable it.toLocaleString it.toString
it.valueOf
it.abi it.address it.allEvents
it.balance it.balanceOf it.constructor
it.contract it.getPastEvents it.methods
it.mintWithTokenURI it.name it.ownedTokens
it.safeTransferFrom it.send it.sendTransaction
it.setTokenUri it.symbol it.tokenOwner
it.tokenURIs it.transactionHash
사용할 수 잇는 변수들을 확인할 수 있습니다.
이제 contract 내에 있는 함수를 테스트 해보면 아래와 같이 할 수 있습니다.
truffle(ganache)> it.mintWithTokenURI("0x2a467DA4a19ACac7D793381E0801b463d49a40D0",10,"happy")
{
tx: '0xb7aa585552c452b53cef4903ef2a4caa50fb563c4dbc1fed606b62f880f361d6',
receipt: {
transactionHash: '0xb7aa585552c452b53cef4903ef2a4caa50fb563c4dbc1fed606b62f880f361d6',
transactionIndex: 0,
blockHash: '0x53b59e086e003ac8ddfb30fe9af3cff768e6cf116f74b474cfd2e0f850acafe5',
blockNumber: 4,
from: '0x2a467da4a19acac7d793381e0801b463d49a40d0',
to: '0xc4d4a60745bdc14dd92ad40909a5d162ce77b803',
gasUsed: 105977,
cumulativeGasUsed: 105977,
contractAddress: null,
logs: [],
status: true,
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
rawLogs: []
},
logs: []
}
위와 같이 mintWithTokenURI function을 실행하여 보았습니다.
이제 제대로 생성됐는지 확인하기 위해 아래와 같이 명령을 입력해보면,
truffle(ganache)> it.balanceOf("0x2a467DA4a19ACac7D793381E0801b463d49a40D0")
BN { negative: 0, words: [ 1, <1 empty item> ], length: 1, red: null }
해당 주소의 balanceOf 명령에 응답으로 1이 나왔음을 알 수 있습니다.
다시 한 번 생성을 해보고 확인을 해보면
truffle(ganache)> it.mintWithTokenURI("0x2a467DA4a19ACac7D793381E0801b463d49a40D0",11,"happy")
{
tx: '0xd729179c6b15775bc9006efac56060c8b2ade22ced218b8c32c753e353ff6a40',
receipt: {
transactionHash: '0xd729179c6b15775bc9006efac56060c8b2ade22ced218b8c32c753e353ff6a40',
transactionIndex: 0,
blockHash: '0x2d23e7a9b2aef66a7863c361965412d27e0c254801abf7f97b686047fcda172c',
blockNumber: 5,
from: '0x2a467da4a19acac7d793381e0801b463d49a40d0',
to: '0xc4d4a60745bdc14dd92ad40909a5d162ce77b803',
gasUsed: 90977,
cumulativeGasUsed: 90977,
contractAddress: null,
logs: [],
status: true,
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
rawLogs: []
},
logs: []
}
truffle(ganache)> it.balanceOf("0x2a467DA4a19ACac7D793381E0801b463d49a40D0")
BN { negative: 0, words: [ 2, <1 empty item> ], length: 1, red: null }
정상적으로 tokenId 2가 생성되고 balanceOf로 확인 시 2개의 token이 할당 됨을 볼 수 있습니다.
Test Code 작성
./test/TestSimpleStorage.sol
상기 경로 내에 예제 Test Code를 작성했습니다.
기본적인 포멧은 해당 코드와 같습니다.
//Klaytn IDE uses solidity 0.4.24 0.5.6 versions.
pragma solidity >=0.4.24 <=0.5.6;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/NFTSimple.sol";
contract TestSimpleStorage{
function testSimpleStorage() public {
NFTSimple it = new NFTSimple();
it.mintWithTokenURI(address(this), 20, "happy");
uint256 ans = it.balanceOf(address(this));
Assert.equal(ans, 3, "value equal test");
}
}
새로 Contract Code를 작성해서 내부에 Test할 Contract의 instance를 생성하고, 원하는 함수를 호출 후 Truffle Assert 함수로 Check하는 식입니다.
현재 해당 코드를 작성 후 Truffle Console에서 Test 하 시에는 아래와 같이 입력합니다.
truffle(ganache)> test
Using network 'ganache'.
Compiling your contracts...
===========================
> Compiling ./test/TestSimpleStorage.sol
> compilation warnings encountered:
/Users/kimdawoon/klaytn/contracts/NFTSimple.sol:40:2: Warning: Variable is shadowed in inline assembly by an instruction of the same name
function balance (address _addr) public view returns(uint){
^ (Relevant source part starts here and spans across multiple lines).
,/Users/kimdawoon/klaytn/contracts/NFTSimple.sol:140:30: Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
function onKIP17Received(address operator, address from , uint256 tokenId, bytes memory data) public returns (bytes4) {
^--------------^
,/Users/kimdawoon/klaytn/contracts/NFTSimple.sol:140:80: Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
function onKIP17Received(address operator, address from , uint256 tokenId, bytes memory data) public returns (bytes4) {
^---------------^
TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException` cannot be used in the REPL
at new NodeError (internal/errors.js:322:7)
at process.<anonymous> (repl.js:349:15)
at process.emit (events.js:412:35)
at process.emit (/usr/local/lib/node_modules/truffle/build/webpack:/~/source-map-support/source-map-support.js:465:1)
at _addListener (events.js:443:14)
at process.addListener (events.js:497:10)
at Runner.run (/usr/local/lib/node_modules/truffle/node_modules/mocha/lib/runner.js:868:11)
at Mocha.run (/usr/local/lib/node_modules/truffle/node_modules/mocha/lib/mocha.js:612:17)
at /usr/local/lib/node_modules/truffle/build/webpack:/packages/truffle-core/lib/test.js:116:1
at new Promise (<anonymous>)
at Object.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/truffle-core/lib/test.js:115:1)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
현재 TypeErr가 나서 정상적으로 결과가 나오지는 않았습니다.
해당 부분은 확인 후 수정 예정이므로 해당 과정만 참고 바랍니다.
상기 오류 부분 수정
truffle 버전을 truffle@nodeLTS로 변경해주시면 test가 정상적으로 수행됩니다.
npm un -g truffle
npm i -g truffle@nodeLTS
이전에 수행하려던 test를 다시 수행하면
test code
//Klaytn IDE uses solidity 0.4.24 0.5.6 versions.
pragma solidity >=0.4.24 <=0.5.6;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/NFTSimple.sol";
contract TestSimpleStorage{
function testSimpleStorage() public {
NFTSimple it = new NFTSimple();
it.mintWithTokenURI(address(this), 20, "happy");
uint256 ans = it.balanceOf(address(this));
Assert.equal(ans, 1, "value equal test");
}
}
코드에서 보다시피 배포한 주소에 1개의 토큰을 mint하고 다시 해당 주소에 대해 balanceOf를 호출한 값과 결과를 비교하게 됩니다.
예상하다시피 1이 나와야 합니다.
truffle(ganache)> test
Using network 'ganache'.
Compiling your contracts...
===========================
> Compiling ./test/TestSimpleStorage.sol
> Compilation warnings encountered:
/Users/kimdawoon/klaytn/contracts/NFTSimple.sol:40:2: Warning: Variable is shadowed in inline assembly by an instruction of the same name
function balance (address _addr) public view returns(uint){
^ (Relevant source part starts here and spans across multiple lines).
,/Users/kimdawoon/klaytn/contracts/NFTSimple.sol:140:30: Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
function onKIP17Received(address operator, address from , uint256 tokenId, bytes memory data) public returns (bytes4) {
^--------------^
,/Users/kimdawoon/klaytn/contracts/NFTSimple.sol:140:80: Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
function onKIP17Received(address operator, address from , uint256 tokenId, bytes memory data) public returns (bytes4) {
^---------------^
> Artifacts written to /tmp/test-2022113-8636-1qrqaru.3vqu
> Compiled successfully using:
- solc: 0.5.6+commit.b259423e.Emscripten.clang
TestSimpleStorage
✓ testSimpleStorage (166ms)
1 passing (7s)
예상했다시피 test를 통과하고 passing된 결과가 나오게 됩니다.