KToken transfer-create转账调用失败,寻求技术排查支持
问题排查:调用
transfer-create转账KToken失败 问题背景
调用transfer-create函数向账户k:81df193e0d913bc87e127150efdaaee39584abbd2d0223ed8c9afb0b31cf9db2转账10枚KToken,执行后返回失败状态。
错误输出
{ "gas": 600, "result": { "status": "failure", "error": { "callStack": [], "type": "EvalError", "message": "", "info": "" } }, "reqKey": "VWFFgiP3fVdMpkwh3HoRNsyJQu5r21K7BrP6IYebTrg", "logs": "QJwoDEUraWkAdNhOm6XLEl1n-VfamHTwY-I-sMfMfGQ", "events": [ { "params": [ "sender00", "k:f89ef46927f506c70b6a58fd322450a936311dc6ac91f4ec3d8ef949608dbf1f", 0.00006 ], "name": "TRANSFER", "module": { "namespace": null, "name": "coin" }, "moduleHash": "rE7DU8jlQL9x_MPYuniZJf5ICBTAEHAIFQCB4blofP4" } ], "metaData": { "blockTime": 1670022922909513, "prevBlockHash": "AZ6zoGd8Bj3OhyOWtf1MpFHGUuTCF1F9bizLDe6zhnA", "blockHash": "mwiya3qCmq6w120nxO_IXZegM8S_FREmm54CbbJQX0k", "blockHeight": 2101 }, "continuation": null, "txId": null }
调用代码
调用语句
await transferCreateKTokenAccount( "ktoken", "k:81df193e0d913bc87e127150efdaaee39584abbd2d0223ed8c9afb0b31cf9db2", 10)
函数实现
async function transferCreateKTokenAccount(sender, newAccount, amount) { const cmd = { networkId: NETWORK_ID, keyPairs: [ Object.assign(KEY_PAIR, { clist: [ Pact.lang.mkCap( "GAS", "Capability to allow buying gas", "coin.GAS", [] ).cap, Pact.lang.mkCap( "Transfer", "Capability to allow coin transfer", "coin.TRANSFER", [sender, newAccount, { decimal: amount }] ).cap ] }) ], pactCode: `(free.ktoken.transfer-create "${sender}" "${newAccount}" (read-keyset "account-keyset") ${amount})`, envData: { "account-keyset": { keys: [ // Drop the k: newAccount.substr(2) ], pred: "keys-all" } }, meta: { creationTime: creationTime(), ttl: 28000, gasLimit: 600, chainId: CHAIN_ID, gasPrice: 0.0000001, // sender: sender sender: `sender00` } }; const response = await Pact.fetch.send(cmd, API_HOST); console.log(`Request key: ${response.requestKeys[0]}`); console.log("Transaction pending..."); const txResult = await Pact.fetch.listen( { listen: response.requestKeys[0] }, API_HOST ); console.log("Transaction mined!"); console.log(JSON.stringify(txResult, null, 2)); } await transferCreateKTokenAccount( `ktoken`, `k:81df193e0d913bc87e127150efdaaee39584abbd2d0223ed8c9afb0b31cf9db2`, 10)
合约实现
;; ; -------------------------------------------------------------------------- ;; ; Fungible-v2 Implementation (defun transfer-create:string ( sender:string receiver:string receiver-guard:guard amount:decimal ) @doc " Transfer to an account, creating it if it does not exist. " @model [ (property (conserves-mass amount)) (property (> amount 0.0)) (property (valid-account-id sender)) (property (valid-account-id receiver)) (property (!= sender receiver)) ] (with-capability (TRANSFER sender receiver amount) (debit sender amount) (credit receiver receiver-guard amount) ) )
失败原因分析
- Capability权限不匹配:合约中
transfer-create使用的是TRANSFERcapability,归属free.ktoken模块,但JS代码里声明的是coin.TRANSFER,权限校验不通过直接导致执行失败。正确的capability应该是free.ktoken.TRANSFER。 - Gas限额不足:当前设置的
gasLimit为600,而创建新账户+转账的组合操作需要更多Gas,建议调高至2000或更高。 - Sender账户不一致:meta中的
sender设为sender00,但实际转账发起账户是ktoken,Gas付费账户与转账账户不一致可能引发权限或余额问题,需将meta的sender改为ktoken。 - 参数类型显式声明缺失:合约中
amount为decimal类型,JS代码直接拼接数字10,虽Pact会自动转换,但建议用(decimal ${amount})显式声明类型,避免潜在类型错误。
内容的提问来源于stack exchange,提问作者att
相关产品推荐
相关产品推荐

