賬實(shí)戰(zhàn):使用 cleos transfer 轉(zhuǎn)移 eosio.token 合約代幣)
區(qū)塊鏈【免費(fèi)下載鏈接】eosAn open source smart contract platform項(xiàng)目地址https://gitcode.com/gh_mirrors/eo/eos點(diǎn)擊查看免費(fèi)下載本指南以 EOSIO 開源智能合約平臺(tái)本倉(cāng)庫(kù) eo/eos中cleos客戶端的transfer子命令為核心完整演示如何將eosio.token合約發(fā)行的代幣如SYS從一個(gè)賬戶轉(zhuǎn)移到另一個(gè)賬戶并深入解析cleos transfer在 programs/cleos/main.cpp 中的底層實(shí)現(xiàn)原理、全部命令行參數(shù)以及相關(guān)測(cè)試用例。閱讀本文后你將掌握轉(zhuǎn)賬命令的標(biāo)準(zhǔn)寫法、參數(shù)語(yǔ)義、權(quán)限模型與常見錯(cuò)誤規(guī)避方法。前置條件在執(zhí)行轉(zhuǎn)賬操作之前需要確認(rèn)以下環(huán)境與知識(shí)均已就緒已安裝當(dāng)前倉(cāng)庫(kù)支持的cleos客戶端。cleos隨 EOSIO 軟件一同構(gòu)建安裝構(gòu)建與安裝方式可參考 docs/00_install/index.md。目標(biāo)網(wǎng)絡(luò)你所連接的鏈上已部署eosio.token合約。只有合約部署后代幣的transferaction 才可被調(diào)用。發(fā)送方賬戶下文示例中的alice持有足夠數(shù)量的待轉(zhuǎn)賬代幣且已解鎖錢包并導(dǎo)入對(duì)應(yīng)私鑰cleos wallet unlock/cleos wallet import。理解以下概念交易transaction一次提交到鏈上的原子操作集合轉(zhuǎn)賬動(dòng)作被封裝在交易中執(zhí)行。轉(zhuǎn)賬不可逆代幣轉(zhuǎn)賬一旦被區(qū)塊確認(rèn)并達(dá)到不可逆狀態(tài)就無(wú)法回滾或撤銷發(fā)送前務(wù)必核對(duì)收款賬戶與金額。核心命令cleos transfercleos transfer是cleos提供的標(biāo)準(zhǔn)代幣轉(zhuǎn)賬子命令其官方功能描述為 Transfer tokens from account to account從賬戶向賬戶轉(zhuǎn)移代幣詳見 docs/02_cleos/03_command-reference/transfer.md?;菊Z(yǔ)法cleos transfer sender recipient amount SYMBOL memo -p senderactive其中四個(gè)位置參數(shù)依次為參數(shù)說明sender轉(zhuǎn)出代幣的賬戶名recipient接收代幣的賬戶名amount轉(zhuǎn)賬數(shù)量格式為數(shù)量 符號(hào)如0.0001 SYS必須用引號(hào)包裹memo隨交易附帶的消息/備注可選但推薦保留便于對(duì)賬標(biāo)準(zhǔn)操作示例以下命令演示從賬戶alice向賬戶bob轉(zhuǎn)賬0.0001 SYS并附帶備注Hodl!cleos transfer alice bob 0.0001 SYS Hodl! -p aliceactive其中alice 轉(zhuǎn)出代幣的賬戶bob 接收代幣的賬戶0.0001 SYS 發(fā)送的SYS代幣數(shù)量Hodl! 隨交易附帶的備注memo-p aliceactive 以alice賬戶的active權(quán)限為交易授權(quán)簽名默認(rèn)為senderactive此處顯式指定更清晰。示例輸出命令執(zhí)行成功后的典型輸出如下不同網(wǎng)絡(luò)與版本可能略有差異此處的輸出為文檔原始示意其中 quantity 展示為25.0000 SYSexecuted transaction: 800835f28659d405748f4ac0ec9e327335eae579a0d8e8ef6330e78c9ee1b67c 128 bytes 1073 us # eosio.token eosio.token::transfer {from:alice,to:bob,quantity:25.0000 SYS,memo:m} # alice eosio.token::transfer {from:alice,to:bob,quantity:25.0000 SYS,memo:m} # bob eosio.token::transfer {from:alice,to:bob,quantity:25.0000 SYS,memo:m}輸出解讀executed transaction: 交易ID交易已在鏈上執(zhí)行成功并給出交易哈希隨后的每一行對(duì)應(yīng)鏈上執(zhí)行時(shí)打印的 action 軌跡第一行是eosio.token合約自身執(zhí)行的transferaction接下來(lái)是發(fā)送方alice與接收方bob因收到通知notify而打印的相同 action 數(shù)據(jù)。全部命令行參數(shù)詳解除了位置參數(shù)cleos transfer還支持以下選項(xiàng)與 docs/02_cleos/03_command-reference/transfer.md 一致它們?cè)?programs/cleos/main.cpp 中以 CLI11 定義選項(xiàng)含義與默認(rèn)值-c, --contract控制該代幣的合約賬戶名默認(rèn)eosio.token。可指定其他實(shí)現(xiàn)了相同transfer接口的合約--pay-ram-to-open由發(fā)送方支付 RAM為接收方打開代幣余額行當(dāng)接收方尚無(wú)該代幣的余額記錄時(shí)使用-x, --expiration交易過期時(shí)間秒默認(rèn) 30 秒-f, --force-unique強(qiáng)制交易唯一。會(huì)消耗額外帶寬防止誤發(fā)相同交易當(dāng) memo 為空時(shí)自動(dòng)在 memo 中注入隨機(jī) nonce見下文源碼解析-s, --skip-sign跳過簽名不使用解鎖錢包中的密鑰簽名-j, --json以 JSON 格式打印結(jié)果--json-file將結(jié)果以 JSON 格式保存到文件-d, --dont-broadcast不廣播交易到網(wǎng)絡(luò)僅打印到 stdout--return-packed與--dont-broadcast配合獲取打包后的交易-r, --ref-block指定用于 TAPOSTransaction as Proof-of-Stake的參考區(qū)塊號(hào)或區(qū)塊 ID--use-old-rpc使用舊版 RPCpush_transaction而非新版send_transaction-p, --permission授權(quán)交易使用的賬戶權(quán)限級(jí)別默認(rèn)senderactive--max-cpu-usage-ms交易執(zhí)行的 CPU 用量上限毫秒默認(rèn) 0 表示不限--max-net-usage交易的網(wǎng)絡(luò)帶寬用量上限字節(jié)默認(rèn) 0 表示不限--delay-sec延遲交易秒數(shù)默認(rèn) 0 秒簡(jiǎn)化數(shù)量參數(shù)當(dāng)省略符號(hào)時(shí)cleos會(huì)按如下規(guī)則處理源碼to_asset邏輯見下文cleos transfer inita tester 1000即省略符號(hào)直接寫數(shù)量。此時(shí)cleos會(huì)先向鏈上查詢eosio.token合約中該符號(hào)的精度信息再對(duì)數(shù)量做精度對(duì)齊不足精度的自動(dòng)補(bǔ)齊小數(shù)位。源碼級(jí)解析cleos transfer 是如何工作的1. 子命令與參數(shù)定義在 programs/cleos/main.cpp 中transfer子命令被定義為string con eosio.token; // 默認(rèn)代幣合約 ... auto transfer app.add_subcommand(transfer, localized(Transfer tokens from account to account)); transfer-add_option(sender, sender, localized(The account sending tokens))-required(); transfer-add_option(recipient, recipient, localized(The account receiving tokens))-required(); transfer-add_option(amount, amount, localized(The amount of tokens to send))-required(); transfer-add_option(memo, memo, localized(The memo for the transfer)); transfer-add_option(--contract,-c, con, localized(The contract that controls the token)); transfer-add_flag(--pay-ram-to-open, pay_ram, localized(Pay RAM to open recipients token balance row)); add_standard_transaction_options_plus_signing(transfer, senderactive);從源碼結(jié)構(gòu)可以確認(rèn)sender、recipient、amount為必填參數(shù)memo可選默認(rèn)合約名為eosio.token默認(rèn)授權(quán)為senderactive。2. 數(shù)量解析與精度對(duì)齊to_asset執(zhí)行回調(diào)中先調(diào)用to_asset將金額字符串解析為資產(chǎn)對(duì)象見 programs/cleos/main.cppasset to_asset( account_name code, const string s ) { static map pairaccount_name, eosio::chain::symbol_code, eosio::chain::symbol cache; auto a asset::from_string( s ); eosio::chain::symbol_code sym a.get_symbol().to_symbol_code(); auto it cache.find( make_pair(code, sym) ); ... auto json call(get_currency_stats_func, ...); // 查詢合約的貨幣統(tǒng)計(jì)get_currency_stats ... if ( a.decimals() expected_symbol.decimals() ) { auto factor expected_symbol.precision() / a.precision(); a asset( a.get_amount() * factor, expected_symbol ); } else if ( a.decimals() expected_symbol.decimals() ) { EOS_THROW(symbol_type_exception, Too many decimal digits in ${a}, only $cpe4elpci5g supported, ...); } return a; }要點(diǎn)cleos會(huì)通過 RPC 調(diào)用合約的get_currency_stats接口查詢符號(hào)對(duì)應(yīng)的最大供應(yīng)量從而獲得該符號(hào)的官方精度用戶給出的金額小數(shù)位數(shù)少于官方精度時(shí)自動(dòng)補(bǔ)齊如1000→1000.0000 SYS小數(shù)位數(shù)超過官方精度時(shí)直接拋出symbol_type_exception錯(cuò)誤拒絕執(zhí)行。這正是轉(zhuǎn)賬時(shí)金額精度必須合法的底層保障。3. 構(gòu)造 transfer actioncreate_transfer隨后調(diào)用create_transfer構(gòu)造鏈上 action見 programs/cleos/main.cppchain::action create_transfer(const string contract, const name sender, const name recipient, asset amount, const string memo ) { auto transfer fc::mutable_variant_object (from, sender) (to, recipient) (quantity, amount) (memo, memo); return action { get_account_permissions(tx_permission, {sender, config::active_name}), name(contract), transfer_n, variant_to_bin( name(contract), transfer_n, transfer ) }; }即向目標(biāo)合約默認(rèn)eosio.token發(fā)出transferaction數(shù)據(jù)結(jié)構(gòu)為{from, to, quantity, memo}授權(quán)級(jí)別取自senderactive。4. --pay-ram-to-open 的底層行為在回調(diào)中programs/cleos/main.cpp如果指定了--pay-ram-to-opencleos會(huì)先構(gòu)造并發(fā)送一個(gè)openaction再發(fā)送transferif (!pay_ram) { send_actions( { transfer }, signing_keys_opt.get_keys()); } else { auto open_ create_open(con, name(recipient), transfer_amount.get_symbol(), name(sender)); send_actions( { open_, transfer }, signing_keys_opt.get_keys()); }create_openprograms/cleos/main.cpp構(gòu)造{owner, symbol, ram_payer}結(jié)構(gòu)ram_payer為發(fā)送方sender。這意味著當(dāng)接收方賬戶從未持有過該代幣其余額行尚未創(chuàng)建時(shí)發(fā)送方可以主動(dòng)承擔(dān) RAM 費(fèi)用幫對(duì)方開戶從而避免轉(zhuǎn)賬因接收方余額表不存在而失敗。5. 強(qiáng)制唯一--force-unique的實(shí)現(xiàn)當(dāng)指定-f/--force-unique且 memo 為空時(shí)cleos會(huì)自動(dòng)生成隨機(jī)字符串注入 memo作為交易的 nonceif (tx_force_unique memo.size() 0) { memo generate_nonce_string(); tx_force_unique false; }這保證了兩次相同的轉(zhuǎn)賬也會(huì)因 memo 不同而生成不同交易 ID防止重復(fù)廣播同一筆交易代價(jià)是額外帶寬消耗。結(jié)合測(cè)試用例理解轉(zhuǎn)賬語(yǔ)義倉(cāng)庫(kù)的單元測(cè)試 unittests/eosio.token_tests.cpp 覆蓋了eosio.token合約的轉(zhuǎn)賬語(yǔ)義可幫助理解真實(shí)鏈上的行為正常轉(zhuǎn)賬transfer( alice_n, bob_n, asset::from_string(300 CERO), hola )驗(yàn)證賬戶間成功轉(zhuǎn)出、余額更新超額轉(zhuǎn)賬向余額不足的賬戶發(fā)起701 CERO轉(zhuǎn)賬會(huì)被拒絕非法金額轉(zhuǎn)賬-1000 CERO負(fù)數(shù)同樣會(huì)被合約拒絕。這些用例印證了雖然cleos transfer負(fù)責(zé)構(gòu)造并廣播交易但金額校驗(yàn)余額充足、數(shù)量為正、精度正確最終由eosio.token合約在鏈上強(qiáng)制執(zhí)行cleos端只是做了前置的精度對(duì)齊。常見問題與注意事項(xiàng)金額必須帶符號(hào)并用引號(hào)包裹0.0001 SYS中的符號(hào)是必須的且cleos會(huì)校驗(yàn)小數(shù)精度省略符號(hào)時(shí)按默認(rèn)精度補(bǔ)齊建議顯式書寫符號(hào)避免歧義。精度超限會(huì)直接報(bào)錯(cuò)若金額小數(shù)位超過合約定義精度cleos拋出Too many decimal digits ... only d supported異常。轉(zhuǎn)賬不可逆區(qū)塊確認(rèn)后無(wú)法撤銷務(wù)必核對(duì)recipient與金額memo建議保留原始信息便于審計(jì)對(duì)賬。接收方無(wú)余額記錄時(shí)可先由發(fā)送方用--pay-ram-to-open幫助對(duì)方開戶或提示接收方先通過其他途徑持有該代幣。授權(quán)級(jí)別默認(rèn)使用senderactive簽名若使用自定義權(quán)限或合約賬戶發(fā)送務(wù)必用-p accountpermission顯式指定。代幣不一定是 SYS-c/--contract可指定控制該代幣的其他合約只要是實(shí)現(xiàn)了標(biāo)準(zhǔn)transfer接口的合約均可按本文流程轉(zhuǎn)賬??偨Y(jié)通過cleos transfer用戶可以便捷地將eosio.token合約發(fā)行的代幣在賬戶間轉(zhuǎn)移。本文從命令語(yǔ)法、參數(shù)選項(xiàng)、示例輸出入手并深入到 programs/cleos/main.cpp 的to_asset、create_transfer、create_open等實(shí)現(xiàn)解釋了金額精度對(duì)齊、默認(rèn)授權(quán)、--pay-ram-to-open開戶與--force-unique防重等底層機(jī)制同時(shí)結(jié)合 unittests/eosio.token_tests.cpp 說明了鏈上校驗(yàn)語(yǔ)義。掌握上述內(nèi)容后即可在實(shí)際網(wǎng)絡(luò)上安全、正確地完成代幣轉(zhuǎn)賬操作。贊分享區(qū)塊鏈【免費(fèi)下載鏈接】eosAn open source smart contract platform項(xiàng)目地址https://gitcode.com/gh_mirrors/eo/eos點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Archon archon-post-review-to-pr 詳解將代碼審查結(jié)果自動(dòng)發(fā)布為 GitHub PR 評(píng)論的確定性 Agent 命令模板Archon archon post review to pr 詳解將代碼審查結(jié)果自動(dòng)發(fā)布為 GitHub PR 評(píng)論的確定性 Agent 命令模板 本文以區(qū)塊鏈EOSIO cleos get currency balance 命令詳解查詢賬戶代幣余額的完整指南EOSIO cleos get currency balance 命令詳解查詢賬戶代幣余額的完整指南 導(dǎo)讀 cleos get currency balanc區(qū)塊鏈WeChatMsg 完整指南3 步免費(fèi)導(dǎo)出微信聊天記錄HTML、Word、CSV 永久保存WeChatMsg 完整指南3 步免費(fèi)導(dǎo)出微信聊天記錄HTML、Word、CSV 永久保存 剛重裝完系統(tǒng)想翻去年和某個(gè)人的聊天新微信里只剩最近幾條記錄。區(qū)塊鏈創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考