ERC20 토큰 발행하려는데 IDE Deploy & Truffle로 스마트 컨트랙 배포 차이

안녕하세요

공식문서대로 따라해보고 있는데요.
0. 스마트 컨트랙 배포를 IDE로 하는 것과 CLI로 하는것의 차이가 있나요?

  1. IDE로 MyERC20.sol & 제 지갑 주소를 입력해서 Deploy를 하면 스마트 컨트랙 주소가 나오던데, 이게 배포된거 맞죠?

  2. terminal로 truffle 이용해서도 배포 해보려고 하는데요.
    truffle-config.js에서 compiler solc version을 0.5.6으로 변경했는데도 계속 아래와 같은 오류가 뜨네요… 어떻게 해야 될까요?

  1. ERC20으로 스마트 컨트랙 배포가 완료됐다면 이후에 API 사용하기 위해서 API와 스마트 컨트랙 연결을 어떻게 해야 될까요?

안녕하세요, 질문 주셔서 감사합니다 :slight_smile:

  1. 스마트 컨트랙 배포를 IDE로 하는 것과 CLI로 하는것의 차이가 있나요?

방법만 다를 뿐 똑같은 내용이 동작한다고 생각하시면 됩니다~
IDE로 작업하고 싶으시면 Remix를 이용하시면 되고,
프로젝트에서 contract deploy를 할 때는 truffle을 많이 이용하더라구요.

  1. IDE로 MyERC20.sol & 제 지갑 주소를 입력해서 Deploy를 하면 스마트 컨트랙 주소가 나오던데, 이게 배포된거 맞죠?

Deploy 후에 컨트랙트 주소가 나왔으면 배포됐다고 생각하시면 될 거 같습니다. 배포가 잘 됐는지 확인하려면 klaytnscope에 한번 검색해 보세요. https://scope.klaytn.com/ 에 접속하시고, 우측 위에 네트워크 맞게 선택하셔서 컨트랙트 주소 검색하시면 됩니다. 결과 보시면 잘 배포되어 있는지, 컨트랙트에 실행된 transaction이 잘 작동하였는지 확인하실 수 있습니다~
아래는 제가 테스트로 바오밥에 배포한 컨트랙트인데, 이렇게 Contract라고 나오면 잘 된 겁니다 :slight_smile:


Klaytnscope.com

  1. terminal로 truffle 이용해서도 배포 해보려고 하는데요.
    truffle-config.js에서 compiler solc version을 0.5.6으로 변경했는데도 계속 아래와 같은 오류가 뜨네요… 어떻게 해야 될까요?

에러 로그 내용은 solidity 파일에 작성한 버전은 0.5.6인데, 현재 컴파일러 버전은 0.4.25라고 되어 있네요. truffle-config.js 파일내에 컴파일러 버전이 0.4.25가 아닌가요? compilers 내용 공유 한번 해주시겠어요?
(evmVersion: "constantinople"인지도 확인해 주세요~ constantinople 이후 버전은 아직 지원하지 않고 있습니다.)
제가 예전에 Baobab에 배포할 때 사용한 truffle-config.js 파일인데 참고 하세요~

  1. ERC20으로 스마트 컨트랙 배포가 완료됐다면 이후에 API 사용하기 위해서 API와 스마트 컨트랙 연결을 어떻게 해야 될까요?

어떤 API를 사용하시는 걸까요? truffle을 이용하고 계시면 caver-js를 이용하실 수 있습니다. 사용하실 caver API들은 https://docs.klaytn.com/bapp/sdk/caver-js 에서 확인하실 수 있습니다~
또한, truffle console을 이용해서 sendTransaction을 편하게 사용하실 수도 있습니다.
truffle console : Redirecting...

truffle console --network baobab
truffle(baobab)> MetaCoin.deployed().then(function(instance) {return instance.sendCoin(a1, 100);}).then(function(value) {console.log(value);});

트랜잭션 결과도 klaytnscope를 통해 확인할 수 있으니 참고하세요~

감사합니다

2개의 좋아요

답변 주셔서 감사합니다…!

  1. 네 klaytn scope에서 확인 가능하네요.

  2. 클레이튼 월렛에다 스마트 컨트랙을 추가했을 때, DKN 100,000으로 표기되는건 초기 발행량을 뜻하는거죠?
    그럼 저 스마트 컨트랙이 제 계좌랑 연동되었다고 볼 수 있는건가요? 제 계좌에는 Klay도 있고 발행한 DKN이랑 토큰도 있는거죠?

  3. local cli에서 진행하던 truffle-config.js 파일입니다.

// const HDWalletProvider = require('@truffle/hdwallet-provider');
// const infuraKey = "fj4jll3k.....";
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();

module.exports = {
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */

  networks: {
	baobab: {
		host: '127.0.0.1',
		port: 8551,
		from: '0x928eba8d7ccdfbd488e57d595dedfc8f6512e447',
  		network_id: '1001', // baobab
  		gas: 20000000, // Transaction Gas limit
  		gasPrice: 25000000000, // Baobab의 gasprice는 25 Gpeb
		},
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.5.6",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      //  evmVersion: "byzantium"
      // }
    }
  }
}
  1. 제가 사용하고 싶은 API는 mint()발행, transfer, 잔액확인 등 이고 이게 가능하다면 나중에는 제 스마트 컨트랙에 접근하려는 유저들한테 지갑 개설 및 접근 가능하게도 하고 싶거든요. 이게 가능할까요?

  2. 만약 스마트 컨트랙을 발행해서 그 주소를 사용하고 있었는데, 토큰 추가 발행을 하기 위해 재배포를 하면 주소가 바뀌니 이전에 연결된 스마트 컨트랙 정보는 다 사라지게 되는건가요? 토큰 추가 발행시 재배포를 안하고 할 수 있는 방법이 있을까요?

  1. 클레이튼 월렛에다 스마트 컨트랙을 추가했을 때, DKN 100,000으로 표기되는건 총 발행가능량을 뜻하는건가요?

account에 DKN 토큰이 100,000개 있다는 건데, DKN이라는 ERC20을 배포한건 아닌지요?

EOA(계좌 주소)와 컨트랙트 주소는 별개입니다. EOA에서 가지고 있는 Klay와 컨트랙트에서 가지고 있는 Klay는 다릅니다. EOA에 있는 Klay를 컨트랙트에 보낼 수 있습니다.
EOA에서 컨트랙트를 배포하면 컨트랙트에 msg.sender 값(배포자)을 저장하여, 이 컨트랙트를 호출할 수 있는 사람을 제한할 수 있습니다. 이것 외에 다른 의미의 연결이 있을까요?

  1. local cli에서 진행하던 truffle-config.js 파일입니다.

PC에 설치된 solidity 버전도 알 수 있을까요?

solc --version
  1. 제가 사용하고 싶은 API는 mint()발행, transfer, 잔액확인 등 이고 이게 가능하다면 나중에는 제 스마트 컨트랙에 접근하려는 유저들한테 지갑 개설 및 접근 가능하게도 하고 싶거든요. 이게 가능할까요?

ERC20을 이용하시는 거면, 컨트랙트에 mint, transfer, balanceof 등의 함수를 작성하시고 sendTransaction을 통해서 진행하면 됩니다.
지갑은 누가 관리하느냐에 따라 달라질 수 있을 것 같습니다.
(1) 메타마스크와 같이 사용자가 직접 관리하는 방법 (non-custodial)
(2) 지갑 개설하여 주는 방법 (custodial)
account 주소에 따른 contract 접근 제어도 contract 내부에서 구현하시면 될 것 같습니다.

  1. 만약 스마트 컨트랙을 발행해서 그 주소를 사용하고 있었는데, 토큰 추가 발행을 하기 위해 재배포를 하면 주소가 바뀌니 이전에 연결된 스마트 컨트랙 정보는 다 사라지게 되는건가요? 토큰 추가 발행시 재배포를 안하고 할 수 있는 방법이 있을까요?

컨트랙트를 interfacing하는 다른 컨트랙트를 작성하시면 됩니다. Interface contract에 실제 구현한 contract의 주소를 가지고 있고, 모든 호출은 Interface contract를 통해서 이루어지면 됩니다.
klaytn 내부코드는 아닌데, 제가 보고 있는 코드들에서 본 내용이라 공유드릴게요 :slight_smile:
예시 1) https://github.com/ConsenSys/quorum/blob/3ad83ba2170839a1f44476e8a15364cb2de3d7f6/permission/v2/contract/PermissionsInterface.sol#L12-L14
예시 2) https://github.com/winnie-byun/chainlink/blob/5afb4835fb2d6294bcbdd0b027646982e653bf6d/evm-contracts/src/v0.6/EACAggregatorProxy.sol#L18

1개의 좋아요

non-custodial은 직접 계정을 생성해 주는 형식이 아닌, 사용자가 별도의 지갑을 가지고 있는 경우입니다. metamask, kaikas, decent, klip 지갑 연동 등을 할 수 있습니다. Klayswap을 이용해 보시면 어떻게 진행되는건지 알 수 있을실 겁니다 :slight_smile:
custodial은 별도의 Key Management Service을 구축 하셔야 합니다.

1개의 좋아요

답변 정말 감사합니다!! 조금씩 이해가 되는데 아직… 확실히는 모르겠네요

  1. 배포 전이 아니라 배포 후에 msg.sender(배포자)를 저장할 수 있다는 말씀이시죠?
    정확히는 스마트 컨트랙을 발행한 EOA의 계좌 주인이 되는 거죠? 이후에 바꿀 수 있는게 아니라

  2. solc version입니다
    npm list solc 아니면 npm show solc version을 해야 나오네요.
    image

truffle을 설치할 때 기본으로 연결된 solidity버전이 0.4.25라서 생기는 문제 같은데, 이건 truffle-config.js에서 다른 버전으로 입력하면 적용이 된다고 나오는데 저만 안되네요;;

  1. API 사용을 여쭙기 전에, API를 쓰려면 KAS에서 토큰 등록을 먼저 해야 되더군요.
    그럴려면 여기 답변처럼 진행을 하려는데, caver-js에서 signuatre값을 가져오려 해도 문제네요

아래 TextDecoder는 node version이 11 이상부터 해결될 수 있다는데…
현재 권장하는 버전이 truffle 4.15, solc 0.5.6, node v10, npm v6 아닌가요?

  1. 배포 전이 아니라 배포 후에 msg.sender(배포자)를 저장할 수 있다는 말씀이시죠?
    정확히는 스마트 컨트랙을 발행한 EOA의 계좌 주인이 되는 거죠? 이후에 바꿀 수 있는게 아니라

스마트 컨트랙트 권한은 설정하기 나름입니다.
msg.sender는 해당 컨트랙트에 함수를 실행한 계정의 주소입니다. contract 배포할 때의 msg.sender는 컨트랙트 배포자가 되는것이지요.
그래서 많은 예시에서 constract constructor에서 msg.sender를 contract owner로 설정합니다.
@okay 님이 컨트랙트내에 owner의 주소를 바꿀 수 있는 함수를 짜실 수도 있고, owner가 여러명이게 만들 수도 있습니다.

그리고 modifier를 정의해서 다른 함수를 실행하기 전 권한 설정을 할 수 있습니다.
예시 : Contracts — Solidity 0.5.3 documentation

  1. solc version입니다
    npm list solc 아니면 npm show solc version을 해야 나오네요.

truffle 버전도 solidity 버전과 통일시켜줬어야 했던 것으로 기억납니다. 저도 예전에 이것 때문에 truffle 삭제 하고 다시 설치해서 해결했던 것 같습니다. 이건 저도 한번 확인해 보고 다시 알려드릴게요.

  1. API 사용을 여쭙기 전에, API를 쓰려면 KAS에서 토큰 등록을 먼저 해야 되더군요.
    그럴려면 여기 답변처럼 진행을 하려는데, caver-js에서 signuatre값을 가져오려 해도 문제네요
    아래 TextDecoder는 node version이 11 이상부터 해결될 수 있다는데…
    현재 권장하는 버전이 truffle 4.15, solc 0.5.6, node v10, npm v6 아닌가요?

지원하는 툴마다 버전이 달라서 문제를 겪고 계신군요. 이건 저희가 한번 맞춰봐야 할 것 같습니다. 일단 지금 truffle-hdwallet-provider-klaytn은 node v10까지 동작하는 것을 확인했습니다. 정식적이진 않지만, node v12 이상에서 truffle을 방법은 있습니다. 불편해도 다음 방법을 이용해 주시면 감사하겠습니다.

1개의 좋아요

@Winnie 답변 감사합니다^^

1. Winnie님은 node, npm, truffle, truffle-hdwallet-xxx, solc, caver-js 등 버전 어떻게 하고 계신가요?
공식문서대로 vvisp 설치하다가 node v10으로 낮춘거였는데 쓰다보니 vvisp가 필요없어서 일단 node11로 올렸고 truffle도 지우고 v5.x 대로 고쳤더니 truffle로 스마트 컨트랙 배포는 돌아가는 듯하네요!

image

이런식으로 에러가 나긴하는데… Winnie님이 설정한 truffle-config.js를 참고할 수 잇을까요?

2. KAS에서 토큰 등록을 해야 token history api를 사용해서 tx 내역을 확인할 수 있는거죠?
다른 계정에서 제 스마트 컨트랙에 접근하여 토큰 transfer를 하거나 요청을 하는 등의 행위를 하려면 wallet API를 사용해야 하는건가요?

3. KAS에서 myERC20으로 발행한 스마트 컨트랙의 토큰 등록을 할 때 고객센터로 문의하라는 에러 메시지가 뜨는데…
이것때문에 어제부터 계속 멈춰있습니다ㅠㅠ 다른 시도를 해보는데 쉽지 않네요
혹시 방법이 있을까요?

1. Winnie님은 node, npm, truffle, truffle-hdwallet-xxx, solc, caver-js 등 버전 어떻게 하고 계신가요?

버전은 @okay 님 프로젝트 맞게 설정하는게 좋을거 같아요
제가 저번에 작업했던 버전입니다. caver를 사용한 프로젝트는 별도라서 이 부분은 안맞을 수도 있을거 같아요.

▶ nvm use 12
Now using node v12.20.1 (npm v6.14.10)
▶ truffle version
Truffle v5.1.63 (core: 5.1.63)
Solidity v0.5.16 (solc-js)
Node v12.20.1
Web3.js v1.2.9
  "dependencies": {
    "caver-js": "^1.5.6",
    "fs": "^0.0.1-security"
  }

truffle-config.js 위에 링크 올려드렸는데, 포럼에서 자동으로 큰 네모로 만들어 버려서 못보셨나보네요 ^^ [링크 : truffle-config.js]

저는 예전에 public EN있을 때 사용한거였고, port지우고 host에 http://127.0.0.1:8551 로 한번 해보시겠어요??

2. KAS에서 토큰 등록을 해야 token history api를 사용해서 tx 내역을 확인할 수 있는거죠?

넵 내역을 tx 내역을 관리하는거면 token history api 를 사용하시는 것이 편하실 거에요.

KAS Docs를 보니 트랜잭션 전송토큰 정보 조회(token history)가 모두 있네요
이 docs보고 따라하시면 될 거 같아요~
제가 caver나 KAS 쪽은 담당아 아니라 정확한 API를 설명드리긴 어려울거 같네요 ㅠ 사용하다가 문제 생기거나 궁금한거 있으시면 caver나 KAS 쪽으로 문의 주시겠어요?

3. KAS에서 myERC20으로 발행한 스마트 컨트랙의 토큰 등록을 할 때 고객센터로 문의하라는 에러 메시지가 뜨는데…

이 쪽도 제가 답변드리기 어려울 거 같네요 죄송합니다
KAS 팀에서도 질문글 보면 답변 드릴 거에요

1개의 좋아요

답변 감사합니다 ^ ^

  1. truffle-config.js 참고해서 진행했는데 에러가 나네요
    node v12.11.0으로 업그레이드 했고, $ npm install truffle-hdwallet-provider-klaytn 했더니 아래와 같은 에러가 뜨네요. $truffle version하면 나오던 truffle, solc, web3 버전도 이젠 갑자기 안나오고, 이런 에러 메시지만 나옵니다.

Error: Cannot find module ‘@truffle/hdwallet-provider’

  • node v12.11.
  • npm v6.11.3
  • truffle v5.1.?

myerc20 npm install truffle-hdwallet-provider-klaytn
npm WARN deprecated mkdirp-promise@5.0.1: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.
npm WARN deprecated tar.gz@1.0.7: ⚠️  WARNING ⚠️ tar.gz module has been deprecated and your application is vulnerable. Please use tar module instead: https://npmjs.com/tar
npm WARN deprecated fs-promise@2.0.3: Use mz or fs-extra^3.0 with Promise Support

> scrypt@6.0.3 preinstall /Users/david/klaytn2/node_modules/scrypt
> node node-scrypt-preinstall.js


> scrypt@6.0.3 install /Users/david/klaytn2/node_modules/scrypt
> node-gyp rebuild

  SOLINK_MODULE(target) Release/copied_files.node
  CC(target) Release/obj.target/scrypt_wrapper/src/util/memlimit.o
  CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/keyderivation.o
  CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/pickparams.o
  CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/hash.o
  LIBTOOL-STATIC Release/scrypt_wrapper.a
  CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/crypto/crypto_scrypt.o
  CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.o
  CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/util/warnp.o
  CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/alg/sha256.o
  CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/util/insecure_memzero.o
  CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.o
  LIBTOOL-STATIC Release/scrypt_lib.a
  CXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_common.o
../src/node-boilerplate/scrypt_common.cc:98:12: warning: address of stack memory associated with local variable
      'scrypt_err_description' returned [-Wreturn-stack-address]
    return scrypt_err_description.c_str();
           ^~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
  CXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_async.o
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:39:14: warning: 'Get' is deprecated: Use maybe version
      [-Wdeprecated-declarations]
      N(obj->Get(Nan::New("N").ToLocalChecked())->Uint32Value()),
             ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:3457:3: note: 'Get' has been explicitly marked
      deprecated here
  V8_DEPRECATED("Use maybe version", Local Get(Local key));
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:311:29: note: expanded from macro
      'V8_DEPRECATED'
  declarator __attribute__((deprecated(message)))
                            ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:39:63: error: too few arguments to function call, single argument
      'context' was not specified
      N(obj->Get(Nan::New("N").ToLocalChecked())->Uint32Value()),
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2611:3: note: 'Uint32Value' declared here
  V8_WARN_UNUSED_RESULT Maybe Uint32Value(
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:40:14: warning: 'Get' is deprecated: Use maybe version
      [-Wdeprecated-declarations]
      r(obj->Get(Nan::New("r").ToLocalChecked())->Uint32Value()),
             ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:3457:3: note: 'Get' has been explicitly marked
      deprecated here
  V8_DEPRECATED("Use maybe version", Local Get(Local key));
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:311:29: note: expanded from macro
      'V8_DEPRECATED'
  declarator __attribute__((deprecated(message)))
                            ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:40:63: error: too few arguments to function call, single argument
      'context' was not specified
      r(obj->Get(Nan::New("r").ToLocalChecked())->Uint32Value()),
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2611:3: note: 'Uint32Value' declared here
  V8_WARN_UNUSED_RESULT Maybe Uint32Value(
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:41:14: warning: 'Get' is deprecated: Use maybe version
      [-Wdeprecated-declarations]
      p(obj->Get(Nan::New("p").ToLocalChecked())->Uint32Value()) {}
             ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:3457:3: note: 'Get' has been explicitly marked
      deprecated here
  V8_DEPRECATED("Use maybe version", Local Get(Local key));
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:311:29: note: expanded from macro
      'V8_DEPRECATED'
  declarator __attribute__((deprecated(message)))
                            ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:41:63: error: too few arguments to function call, single argument
      'context' was not specified
      p(obj->Get(Nan::New("p").ToLocalChecked())->Uint32Value()) {}
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2611:3: note: 'Uint32Value' declared here
  V8_WARN_UNUSED_RESULT Maybe Uint32Value(
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
../src/node-boilerplate/inc/scrypt_async.h:53:17: warning: 'Call' is deprecated [-Wdeprecated-declarations]
      callback->Call(1, argv);
                ^
../../nan/nan.h:1741:3: note: 'Call' has been explicitly marked deprecated here
  NAN_DEPRECATED inline v8::Local
  ^
../../nan/nan.h:106:40: note: expanded from macro 'NAN_DEPRECATED'
# define NAN_DEPRECATED __attribute__((deprecated))
                                       ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:35:36: error: too few arguments to function call, single
      argument 'context' was not specified
      maxtime(info[0]->NumberValue()),
              ~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2608:3: note: 'NumberValue' declared here
  V8_WARN_UNUSED_RESULT Maybe NumberValue(Local context) const;
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:36:39: error: too few arguments to function call, single
      argument 'context' was not specified
      maxmemfrac(info[1]->NumberValue()),
                 ~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2608:3: note: 'NumberValue' declared here
  V8_WARN_UNUSED_RESULT Maybe NumberValue(Local context) const;
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:37:36: error: too few arguments to function call, single
      argument 'context' was not specified
      maxmem(info[2]->IntegerValue()),
             ~~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2609:3: note: 'IntegerValue' declared here
  V8_WARN_UNUSED_RESULT Maybe IntegerValue(
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:38:39: error: too few arguments to function call, single
      argument 'context' was not specified
      osfreemem(info[3]->IntegerValue())
                ~~~~~~~~~~~~~~~~~~~~~ ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:2609:3: note: 'IntegerValue' declared here
  V8_WARN_UNUSED_RESULT Maybe IntegerValue(
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:351:31: note: expanded from macro
      'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
                              ^
../src/node-boilerplate/scrypt_params_async.cc:23:8: warning: 'Set' is deprecated: Use maybe version
      [-Wdeprecated-declarations]
  obj->Set(Nan::New("N").ToLocalChecked(), Nan::New(logN));
       ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:3402:3: note: 'Set' has been explicitly marked
      deprecated here
  V8_DEPRECATED("Use maybe version",
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:311:29: note: expanded from macro
      'V8_DEPRECATED'
  declarator __attribute__((deprecated(message)))
                            ^
../src/node-boilerplate/scrypt_params_async.cc:24:8: warning: 'Set' is deprecated: Use maybe version
      [-Wdeprecated-declarations]
  obj->Set(Nan::New("r").ToLocalChecked(), Nan::New(r));
       ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:3402:3: note: 'Set' has been explicitly marked
      deprecated here
  V8_DEPRECATED("Use maybe version",
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:311:29: note: expanded from macro
      'V8_DEPRECATED'
  declarator __attribute__((deprecated(message)))
                            ^
../src/node-boilerplate/scrypt_params_async.cc:25:8: warning: 'Set' is deprecated: Use maybe version
      [-Wdeprecated-declarations]
  obj->Set(Nan::New("p").ToLocalChecked(), Nan::New(p));
       ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8.h:3402:3: note: 'Set' has been explicitly marked
      deprecated here
  V8_DEPRECATED("Use maybe version",
  ^
/Users/david/Library/Caches/node-gyp/12.11.0/include/node/v8config.h:311:29: note: expanded from macro
      'V8_DEPRECATED'
  declarator __attribute__((deprecated(message)))
                            ^
../src/node-boilerplate/scrypt_params_async.cc:32:13: warning: 'Call' is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
            ^
../../nan/nan.h:1741:3: note: 'Call' has been explicitly marked deprecated here
  NAN_DEPRECATED inline v8::Local
  ^
../../nan/nan.h:106:40: note: expanded from macro 'NAN_DEPRECATED'
# define NAN_DEPRECATED __attribute__((deprecated))
                                       ^
8 warnings and 7 errors generated.
make: *** [Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_async.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:196:23)
gyp ERR! stack     at ChildProcess.emit (events.js:210:5)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Darwin 19.6.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/david/klaytn2/node_modules/scrypt
gyp ERR! node -v v12.11.0
gyp ERR! node-gyp -v v5.0.3
gyp ERR! not ok
npm WARN ajv-keywords@3.5.2 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.
npm WARN klaytn2@1.0.0 No description
npm WARN klaytn2@1.0.0 No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! scrypt@6.0.3 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the scrypt@6.0.3 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/david/.npm/_logs/2021-04-08T09_05_12_623Z-debug.log
  1. truffle 설치 후 truffle hdwallet을 설치해야 winnie 님이 작성하신 truffle-config.js를 이용해 스마트컨트랙 배포하거나 배포한 거에 접근할 수 있는거죠?

일단 truffle-hdwallet-provider-klaytn이 node 12에서는 제공안하는거 같은데 맞나요?
node 11로 다운그레이드하고 npm install truffle-hdwallet-provider-klaytn을 했을 때 여러 warning은 뜨는데 error는 안뜨긴 하네요.
그리고 truffle version을 입력하면 아까처럼 cannot find moudle '@truffle/hdwallet-provider’는 동일하고요
다시 처음부터 해야될거 같습니다…윽…

이 링크 한번 읽어봐 주세요~
@truffle/hdwallet-providerklaytn/truffle-hdwallet-provider-klaytn#v5.1.63-klaytn을 설치하는 방법 2가지가 있습니다. 두 가지 방법 둘 다 잘 작동합니다~

  1. truffle 설치 후 truffle hdwallet을 설치해야 winnie 님이 작성하신 truffle-config.js를 이용해 스마트컨트랙 배포하거나 배포한 거에 접근할 수 있는거죠?

네~ truffle과 truffle hdwallet 설치해야 됩니다

1개의 좋아요

까먹을때마다 와서 보는데 친절히 답변 해주셔서 감사합니다ㅎㅎ

몇가지 더 질문이 생겨서요!

  1. 계정과 지갑은 어떤 차이가 있나요?
    1개의 지갑에 여러개의 계정이 생기는 개념인가요? 그래서 klaytnWallet과 KAS API로 만든 계정이 연결이 안되는건가요?

  2. baobab에 KIP7토큰을 배포해서 사용중인데요. caver-js-ext-kas를 사용할 때도 caver.kas.wallet.createAccount()를 할 수 있는데 이게 계정인가요? 지갑인가요? 당연히 계정이겠거니 싶은데 지갑이 있어야 계정이 있는거 아닌가요?
    지갑은 KAS에서 AccessKeyID를 생성할 때 자동으로 만들어지는건가요?

createAccount()실행시 나오는 화면인데요. KlaytnWallet에 연결하려면 PrivateKey가 필요한데 그게 없어서 어떻게 사용해야될지를 모르겠네요.

  1. 스마트 컨트랙을 배포한 뒤 내용을 수정하고 재배포가 가능한가요?
    만약 mainNet에 실제 토큰을 발행해서 사람들이 사고 팔고 있는 상황인데 컨트랙 수정 후 재배포를 하면 새로운 토큰이 되어버리는거 아닌가요? 기 배포된 토큰으로 일치시키는 방법 궁금합니다.

  2. transfer()를 하면 클레이튼은 1초 안에 블록 생성이 되서 처리가 가능하다 들었는데, 서버에서 웹 훅을 따로 기다리는 게 아니라 동기식으로 1초동안 기다리는 식으로 처리되는거죠??

안녕하세요 ^^

  1. 지갑에 대해 아시려면 metamask나 kaikas 사용해 보세요 ^^
    여러 계정을 추가할 수도 있고 원하는 네트워크에 붙을 수도 있습니다~
    그리고 몇 클레이를 소유중인지도 바로 보실 수 있습니다.
    계정은 이 문서를 통해 생성하실 수 있습니다.
    private, public key pair를 생성하는 과정이구요, public key가 네트워크의 주소가 됩니다.
    네트워크 별로 다른 계정을 사용하실 수도 있고, private key를 알고 있다면 다른 네트워크에서 같은 주소로 이용하실수도 있습니다
  2. 제가 KAS나 caver 쪽 담당은 아니라서 답변해 드리기 어려울 것 같네요 ^^
    다른 분들에게 물어보시는게 정확하실 것 같습니다.
    제가 알기론 KAS가 custodial wallet이라서, 직접 키를 관리해 주는 형태입니다. 저기 krn을 통해 KAS를 접근하면 KAS내에서 해당 private key를 가져오는 구조입니다.
    직접 private key를 보거나 등록하는 방법은 없다고 알고 있습니다
  3. 스마트 컨트랙트를 재배포하면 기존 정보를 유지하기 힘들죠
    스마트 컨트랙트를 나누는 방법은 어떠실까요?
    token 정보를 가지고 있는 contract와 구현 contract를 나누면 될 것 같습니다.
    modifier와 다른 contract 주소 저장을 하면 충분히 구현 가능하실 거에요~
  4. klaytn node의 klay_sendtransaction을 말씀하시는거면 tx pool에 넣는것 까지가 동기로 동작하고, tx pool에서 블록에 넣기까지는 별도의 thread로 동작합니다
    caver-js는 sendtransaction을 말씀하시는거면 docs에서 적혀있는 것처럼 promievent를 return합니다. promise이자 event라서 유연하게 처리하실 수 있습니다~
1개의 좋아요

답변 감사합니다.

1. 지갑과 계정에 대한 개념이 헷갈리네요
메타마스크, 카이카스 둘 다 설치해봤는데요.
제가 klaytnWallet에서 생성한 계정에는 address, private key, klaytnwalletkey밖에 없는데 metamask에서 기존 계정과 연결할 때는 시드 구문을 요구하더라고요. 시드 구문은 어디서 가져올 수 있는거죠?

이 부분에서 네트워크는 계정이나 지갑을 이야기하는게 아니라 baobab인지 mainnet인지를 말씀하시는거죠?

네트워크 별로 다른 계정이란 말도 testnet/mainnet 별로 다른계정을 사용할 수도 있고 같은 계정을 사용할 수도 있다 이말인거죠?

2. 스마트 컨트랙트 재배포
배포를 kip7token.sol을 그대로 가져와서 사용해서 그런지… 스마트 컨트랙을 나눠서 사용하라는 말이 이해가 잘 안되네요.
1) 토큰을 발행하는 컨트랙2) 함수가 구현된 컨트랙을 따로 두면, 발행할때 쓰는 컨트랙은 초기발행이나 mint(추가발행)로만 사용하는 거고 나머지 transfer나 transcation 조회 등에 사용되는 컨트랙은 따로 쓰고 나중에 수정도 한다. 이말인건가요?
조금 더 자세히… 말씀해주시면 감사하겠습니다^^ 예시를 들어주시면 더 좋고요

만약 나눠서 사용하지 않는다면 발행 & 구현 모두 한꺼번에 되지만, 추가 배포를 하면 기존에 발행했던 토큰과 다른 토큰이 생기기 때문에 사실상 여러 토큰이 생기게 되는거죠? 그러면 사실상 다른 토큰이 되어버리는…