결과
← 400 Bad Request https://wallet-api.klaytnapi.com/v2/tx/contract/execute (259ms)
content-type: application/json; charset=utf-8
date: Thu, 19 Nov 2020 07:45:28 GMT
content-length: 81
x-envoy-upstream-service-time: 10
server: istio-envoy
{“code”:1065100,“message”:“failed to get an account from AMS; data don’t exist”}
를 해서 만들면 아래와 같은 정보가 뜨는데요.
KAS를 이용해 스마트 컨트랙에 접근하려면 아래 화면에 나오는 address를 from 에 가져다 쓰면 되는거죠?
근데 Klay가 0이라 insufficient funds of te sender for value는 그대로 아닌가요? 그렇다고 Private Key나 KeystoreFile(.json)이 만들어진것도 아니라서 KlaytnWallet.com에서 접근하여 Klay Faucet 을 할 수도 없고요
어떻게 해야될까요?
말씀하신대로 global fee payer를 이용하면 KAS에서 수수료를 대납하는거잖아요?
그래서 Fee Delegated Transaction를 쓰려고 하는데 아래 코드 부분에 어떻게 넣어야될까요?
주신 POST 부분(“http://localhost/v2/tx/fd/value”)을 어떻게 caver.kas 이런식으로 부를지 모르겠습니다.
const CaverExtKAS = require('caver-js-ext-kas')
const caver = new CaverExtKAS()
그러면 KlaytnWallet.com에서 KAS를 이용해 만든 Wallet을 연결하고 Run Faucet을 하려면 어떻게 해야 될까요?? 터미널에 Private Key는 나오지 않더라고요
이 링크도 참고 부탁드리겠습니다. Wallet API로 새로 두 계정을 만들고 두 계정간 0 KLAY를 전송하는 예제코드를 전달드립니다.
const Caver = require('caver-js')
const CaverExtKAS = require('caver-js-ext-kas')
// Configuration Part
// Set your KAS access key and secretAccessKey.
const accessKeyId = ''
const secretAccessKey = ''
// const CHAIN_ID_BAOBOB = '1001'
// const CHAIN_ID_CYPRESS = '8217'
const chainId = '1001'
const option = {
headers: [
{ name: 'Authorization', value: 'Basic ' + Buffer.from(accessKeyId + ':' + secretAccessKey).toString('base64') },
{ name: 'x-chain-id', value: chainId },
]
}
const caver = new CaverExtKAS()
main()
async function main() {
caver.initKASAPI(chainId, accessKeyId, secretAccessKey)
var acc1 = await caver.kas.wallet.createAccount()
var acc2 = await caver.kas.wallet.createAccount()
var result = await caver.kas.wallet.requestFDValueTransferPaidByGlobalFeePayer({
from: acc1.address,
to:acc2.address,
value:0,
submit:true
})
console.log('result', result)
}
Wallet API에서 생성한 계정은 private key가 암호화되어 누구도 알 수 없습니다. Baobab faucet에서 새로 계정을 만드시고 그 계정에서 Wallet API로 만든 계정으로 KLAY를 전송하시면 될 것 같습니다.
아직 대납기능을 지원하는 기능이 구현중이라서 현재는 코드가 좀 복잡하네요. caver v1.6.1에서 컨트랙트에 대납 기능이 추가되었으나 아직 KAS와 연동하는 부분은 추가 기능 구현이 필요합니다. 아래 코드를 이용해 현재 상황에서도 대납 기능을 이용할 수는 있습니다. 좀 복잡하지만요. 아래 예제 코드를 전달드립니다.
KlaytnWallet에서는 DTK에 빨간 박스를 그려주셨고, scope쪽에서는 KLAY에 빨간 박스를 그려주셨네요. 질문이 명확하게 이해하진 못했으나, 설명을 좀 적어보겠습니다. scope에서도 동일한 네트워크에서 동일한 계정을 조회하시면 동일한 KLAY 잔고를 확인하실 수 있습니다. KlaytnWallet쪽에서는 0x9로 시작하는 계정의 잔고를 확인하신거니, scope에서도 0x9로 시작하는 계정의 잔고를 조회하시면 될 것 같습니다. DTK에 대해서도 마찬가지고요.
스마트 컨트랙을 발행할 때 연결된 계정을 Owner라고 한다면,
Owner ------ “100 DTK” --------> A 계정 을 구현할때는 kip7.transfer()를 이용했는데요
A 계정 ------------- 100 DTK ---------> B계정을 구현하려고 할때 사용해야될 API가 caver.transaction.feeDelegatedSmartContractExecution()라는건가요? (Klay가 아니라 자체 토큰을 보내고 싶은겁니다)
스마트 컨트랙을 발행한 계정이 아니라면 대납을 해줘야되는건가요?
그리고 말해주신대로 했는데 여전히 gas required exceeds allowance or always failing transaction 에러가 나네요.
참고해서 적은 코든데 receiver.address, ide_wallet.address에는 다 Klay가 있습니다.
혹시 contract Address에 Klay가 없어서 그런가요? 근데 contract Address에 Klay 전송은 안되더라고요
async function sendToken(){
console.log('sending Token......')
try{
const c = new caver.contract(kip7JsonInterface, contractAddress)
const transferInput = await c.methods['transfer'](receiver.address, 10).encodeABI()
var transferTx = new caver.transaction.feeDelegatedSmartContractExecution({
from: ide_wallet.address,
to: contractAddress,
input: transferInput,
gas: 10000
})
await caver.wallet.sign(ide_wallet.address, transferTx)
} catch(err){
console.log('err : ',err)
}
}
sendToken()
A → B에도 기본적으로는 kip7.transfer()를 이용하시면 되는데, A계정이 Wallet API계정이라면 caver-js-ext-kas가 아닌 caver-js를 이용해서는 (private key가 없기 때문에) 토큰을 전송하실 수 없습니다.
추후에 KAS KIP-7 API가 나오면 좀 더 쉬운 방법이 제공될 예정인데, 아직은 제공되지 않는 기능이라서, 현재는 caver-js를 이용해 트랜잭션을 만들고 signature는 채우지 않은 상태에서 RLP를 전송하는 방법이 간단한 방법입니다.
KLAY를 보내시려면 ValueTransfer 트랜잭션이 필요합니다. 만약 자체 토큰 등 스마트 컨트랙트를 실행하고 싶으시면 Smart contract execution 트랜잭션이 필요하고요. 대납은 이 기능과는 별개로 sender가 KLAY가 없을 때 다른 계정의 KLAY를 이용해 transaction fee를 납부하려고 할 때 사용할 수 있습니다. value transfer transaction도 smart contract execution transaction도 모두 대납 기능을 이용할 수 있습니다.
Transaction type에 대한 상세 설명은 이 링크에서 확인하실 수 있습니다.
gas required exceeds allowance라는 에러가 뜨신다면 transaction object의 gas값을 좀 더 큰 값으로 설정하시길 바랍니다.
caver-js-ext-kas를 이용중이라면, 계정을 KlaytnWallet 웹으로 만들던 KAS를 이용해 만들던 상관없이 쓸 수 있다는 말씀이신거죠?
KlaytnWallet으로 만든 계정을 스마트 컨트랙 발행할 때 연결했더니, kip7.transfer()를 할 때 keyring을 꼭 해줘야되더라고요. KAS createAccount로 만든 계정이라면 keyring을 안해도 되나요? keyring은 KAS화 시키는 작업이라 생각하면 되나요? (좀전에 위에서는 caver-js-ext-kas를 쓰면 다 쓸 수 있다고 가정했는데… 그게 아닌건가요?)
createAccount를 하면 address와 publicKey만 나오는데 이거 PrivateKey와 klaytnWalletKey가 없어서 지갑으로 사용 불가한거 아닌가요?
반면 generateSingleKey()함수를 이용하면 아래와 같이 주소와 private Key가 생성되니까 이게 지갑으로 사용이 가능하고요.
그러다보니 createAccount()를 무슨 용도로 사용해야될지를 모르겠습니다.
4. 지갑과 계정의 차이
KlaytnWallet 웹에서도 CreateAccount를 하면 지갑과 계정이 동시에 생기잖아요?
1개의 계정에 1개의 지갑이라고 생각을 하면 되죠? 혹은 1개의 계정이 여러개의 지갑을 소유하는 거고요?
그렇다면 caver-js-ext-kas를 이용해서 caver.kas.wallet.createAccount()를 하면… 각각의 계정&지갑이 생성된다고 보면 되는건가요?
네 상관없이 쓰실 수 있지만 사용방법은 좀 다릅니다.
KlaytnWallet을 통해 만드신 계정은 직접 private key를 caver-js wallet으로 import해서 사용하셔야 하고요 (참고)
KAS Wallet으로 생성한 계정을 이용하시려면 이 문서 참고 부탁드립니다. 참고로, caver-js-ext-kas는 caver-js를 wrapping하여 만든 라이브러리이기 때문에, caver-js의 기능을 모두 이용하실 수 있습니다.
음… 기본적으로, 어찌되었건 트랜잭션에 private key로 서명하는 과정이 필요합니다. KlaytnWallet에서 만든 계정은 private key를 따로 추출하여서 caver-js를 통해 서명을 직접 하셔야 합니다. KAS를 사용하신다면 서명 과정은 KAS API가 담당해서 처리를 하니, 생성된 계정의 주소와 KAS credential을 전달하면 KAS Wallet API 내부적으로 서명이 일어나게 되고요.
과정을 좀 더 세분화해서 설명을 해보겠습니다. KlaytnWallet의 예를 보면,
1- KlaytnWallet을 통해 account A 생성 (private key도 같이 생성됨)
2- 생성된 private key를 caver.wallet을 통해 import
3- tx.from=A로 트랜잭션 생성
4- signedTransaction = caver.wallet.sign(A, tx)
5- signedTransaction을 Klaytn network (Cypress)로 전송
의 과정을 통해 트랜잭션 생성, 서명, 전파가 되고, 전파된 트랜잭션이 블록에 들어가게 되면 그게 실제 블록체인에 최종 결과로 들어가게 됩니다.
KAS는 이 과정을 쉽게하고, private key 관리를 내부적으로 해 준다고 생각하시면 됩니다. KAS를 쓰게되면 절차가 아래와 같이 바뀌게 됩니다.
1- KAS Wallet API를 통해 account B create (private key는 KAS 내부에 저장됨)
2- tx.from=B로 트랜잭션 생성
3- KAS Wallet API를 통해 트랜잭션 서명 및 전송 (submit = true일 경우 바로 Cypress로 전송됨)
KAS를 사용할 경우에는 보안을 위해 KAS 내부에서 생성한 private key만을 사용할 수 있기 때문에, createAccount()로만 클레이튼 계정을 생성할 수 있습니다.
계정과 지갑이라는 용어가 명확히 정의되지 않아 생기는 문제 같습니다. 지갑은 여러개의 계정을 관리하고 트랜잭션에 원하는 계정의 서명을 추가하는 역할을 포함한다고 생각하시면 됩니다. 계정은 단순히 Klaytn에서 관리되는 KLAY balance를 가진 하나의 자료구조라고 생각하시면 되고요. 위에 말씀하신 것을 바탕으로 보자면 지갑이라는 용어는 빼셔도 될 것 같습니다.