(三) 用 JavaScript 寫 DApp:FO 轉賬

FO 是官方在 FibOS 發行的數字貨幣,也在多個交易所上交易,做者在寫文章的時候,大概報價是 0.05 元。官方也推出了一個簡潔易用的錢包 APP 供你們管理本身的 FO 資產,有興趣的同窗也能夠下載使用(https://wallet.fo/zh-cn)。有 FO 帳戶尚未 FO 的小夥伴不妨留下 FO 帳戶,說不定我會抽幾個給你們打 FO 呢。html

可是怎麼打 FO 呢,很簡單,你們能夠 FO 錢包 APP 中點擊轉賬,輸入收款帳戶和轉帳數量後點肯定一鼓作氣。node

可是例如咱們在一些須要大批量轉帳或自動化轉帳的狀況下,咱們如何經過代碼實現呢?接下來我帶領你們一塊兒來體驗一下:npm

1. 建立項目

咱們建立一個文件夾叫 transfer,而且進入該文件夾:json

mkdir transfer
cd transfer

初始化項目。咱們能夠執行 fibos 命令是由於咱們已經安裝了 fibos 命令行工具。若是不清楚如何安裝的能夠閱讀我本專欄的前一篇文章。api

fibos --init

安裝 fibos 依賴包。這裏能夠 使用 fibos 安裝也能夠選擇 npm 命令安裝。固然若是您安裝特別慢,可使用 cnpm 或者淘寶 npm 鏡像。網絡

fibos --install fibos.js

到此爲止,準備工做就作完了。此時你的 transfer 文件夾的目錄結構是這樣的:app

.
├── node_modules
└── package.json

2. 主網和測試網介紹

這裏須要解釋一下的是,咱們在開發過程當中常常碰到的鏈主要有三類:ide

  • 主鏈/主網(Main Chain / Main Net),是由 21 個投票當選的節點負責出塊。咱們上述說到的價值 0.05 的 FO 就記錄在主鏈上。
  • 測試鏈/測試網 (Test Chain / Test Chain),測試鏈運行着跟主鏈如出一轍的機制,就是你們都知道這是一條開發用來測試的鏈,上面的 FO 並無價值。
  • 本地鏈/本地網。這個是我生造的一個詞。根據官網:https://dev.fo/zh-cn/guide/tu... 的介紹應該是在本地生成一個鏈或者網,只是只有你一個節點。官網上的說法感受容易產生誤解。

上述三個鏈或者網徹底隔離。你們不要搞混了。函數

主鏈:工具

ID:6aa7bd33b6b45192465afa3553dedb531acaaff8928cf64b70bd4c5e49b7ec6a
EndPoint: http://api.fibos.me  
# 固然還有其餘,能夠在官方文檔中查詢:節點介紹 — Dev.fo

測試鏈:

ID:68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a
EndPoint:http://api.testnet.fo
這裏咱們爲了快速開始,建議使用測試網絡,減小工做量和沒必要要的坑打擊積極性。

咱們能夠在測試網的網站上建立幾個測試帳戶並給幾個帳戶空投幾個 FO,建立方法:

目前我申請了兩個帳戶,而且空投了一些測試鏈的 FO。分別是:

帳戶: gtcmpcrcm2h5
私鑰: 5JVtt2nHcr52xfULsRCAKGAFDuCazWs5Z1RcvZmerE8W3Fr66UL
公鑰: FO7zZJJdfTvGKpdudAcYQp1y97wP9cC9vG2McmeWzvgLWVnkVy9m

帳戶: cmvdkvfgedjg
私鑰: 5JBoQimR9kDB4922S7BaDjQnm8zaD5D2qNXRbbVKZryRCdUxhfc
公鑰: FO7wwaYC7r1z1sP7xyBBa9prEt7dFNoMXY9ZMREEyRUYxKgx4KD4

⚠️ 注意:此處是測試鏈,且爲了方便你們才列在這裏。千萬千萬不要在任何地方泄露你的私鑰,泄露表明資產丟失。

3. 初始化客戶端

一切準備就緒,咱們要實現轉帳,咱們須要獲取一個客戶端。咱們在目錄下建立一個 initClien.js 文件,編寫如下代碼:

var FIBOS = require('fibos.js');

function initClient(_keyProvider) {
    return FIBOS({
        chainId: '68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a',
        keyProvider: _keyProvider,
        httpEndpoint: 'http://api.testnet.fo',
        logger: {
            log: null,
            error: null
        }
    });
}

module.exports = initClient;

其中 chainId 即鏈的 ID,這裏咱們接入測試鏈,因此輸入的是測試鏈的 ID。httpEndpoint 即爲接入點,也是測試鏈的接入點。_keyProvider 爲要建立 Client 的那個帳戶的私鑰,咱們後續會以參數的形式傳入。

此時目錄結構爲:

.
├── initClient.js
├── node_modules
└── package.json

4. 轉賬

咱們在目錄中新建一個 transfer.js 文件,在文件中編碼:

var FIBOS = require('./initClient.js')
    var config = {
        'public-key': 'FO7zZJJdfTvGKpdudAcYQp1y97wP9cC9vG2McmeWzvgLWVnkVy9m', // FO 轉出方私鑰
        'private-key': '5JVtt2nHcr52xfULsRCAKGAFDuCazWs5Z1RcvZmerE8W3Fr66UL' // FO 轉入方私鑰
    };

console.log(config['private-key'])
var fibos = FIBOS(config['private-key']);

let ctx = fibos.contractSync('eosio.token');
var r = ctx.transferSync(
    'gtcmpcrcm2h5',  // FO 轉出方
    'cmvdkvfgedjg',   // FO 轉入方
    '0.1000 FO',  // FO數量
    'Hello Fibos',  // 附言
    {
  authorization: 'gtcmpcrcm2h5' // FO 轉出方帳戶
});
console.log(r);

此時目錄結構爲:

.
├── initClient.js
├── node_modules
├── package.json
└── transfer.js

執行如下命令進行轉帳:

fibos transfer.js

成功後會輸出此次轉帳的詳情:

{
  "broadcast": true,
  "transaction": {
    "compression": "none",
    "transaction": {
      "expiration": "2019-07-03T11:49:58",
      "ref_block_num": 52798,
      "ref_block_prefix": 459488456,
      "max_net_usage_words": 0,
      "max_cpu_usage_ms": 0,
      "delay_sec": 0,
      "context_free_actions": [],
      "actions": [
        {
          "account": "eosio.token",
          "name": "transfer",
          "authorization": [
            {
              "actor": "gtcmpcrcm2h5",
              "permission": "active"
            }
          ],
          "data": "509a90e8a22a5166c05e526c6d98b644e80300000000000004464f00000000000b48656c6c6f204669626f73"
        }
      ],
      "transaction_extensions": []
    },
    "signatures": [
      "SIG_K1_K46edAAzozP1bThRBGnkNX5M11z4kVBzAAt4qrLZfFVcqaUBhsww3rBdiYgxvhdy3K39bZso1uZGMTp6PEMiQQiDWZATnx"
    ]
  },
  "transaction_id": "5dc6a856f8821a395993a083945e919eb19c0dc277c2a88e60ea31655cc07fba",
  "processed": { ... }

5. 常見錯誤

Provided keys, permissions, and delays do not satisfy declared authorizations
{

"code":500,
"message":"Internal Service Error",
"error":{
    "code":3090003,
    "name":"unsatisfied_authorization",
    "what":"Provided keys, permissions, and delays do not satisfy declared authorizations",
    "details":[
        {
            "message":"transaction declares authority '{"actor":"cmvdkvfgedjg","permission":"active"}', but does not have signatures for it under a provided delay of 0 ms, provided permissions [], provided keys ["FO7zZJJdfTvGKpdudAcYQp1y97wP9cC9vG2McmeWzvgLWVnkVy9m"], and a delay max limit of 3888000000 ms",
            "file":"authorization_manager.cpp",
            "line_number":520,
            "method":"check_authorization"
        }
    ]
}

}
檢查 transfer.js 文件中的公鑰、私鑰和 authorization 是否正確,並且都是 FO 轉出方的。這裏官網的示例代碼註釋寫錯了:https://dev.fo/zh-cn/guide/to...

symbol precision mismatch

{
    "code":500,
    "message":"Internal Service Error",
    "error":{
        "code":3050003,
        "name":"eosio_assert_message_exception",
        "what":"eosio_assert_message assertion failure",
        "details":[
            {
                "message":"assertion failure with message: symbol precision mismatch",
                "file":"wasm_interface.cpp",
                "line_number":924,
                "method":"eosio_assert"
            },
            {
                "message":"pending console output: ",
                "file":"apply_context.cpp",
                "line_number":72,
                "method":"exec_one"
            }
        ]
    }
}

FO 的精度錯誤,FO 數量必定要寫四位小數。多了少了都會報這個錯誤。

missing contract
/Users/charlie/Code/fibos/transfer/node_modules/_eosjs@16.0.2@eosjs/lib/structs.js:546:7
      assert(contract != null, 'missing contract');
      ^
Error: missing contract extransfer.quantity action.data transaction.actions
    at Object.fromObject (/Users/charlie/Code/fibos/transfer/node_modules/_eosjs@16.0.2@eosjs/lib/structs.js:546:7)
    at Object.fromObject (/Users/charlie/Code/fibos/transfer/node_modules/_fcbuffer@2.2.0@fcbuffer/lib/struct.js:151:34)
    at actionDataFromObject (/Users/charlie/Code/fibos/transfer/node_modules/_eosjs@16.0.2@eosjs/lib/structs.js:753:29)
    at Object.fromObject (/Users/charlie/Code/fibos/transfer/node_modules/_fcbuffer@2.2.0@fcbuffer/lib/struct.js:148:15)
    at Object.fromObject (/Users/charlie/Code/fibos/transfer/node_modules/_fcbuffer@2.2.0@fcbuffer/lib/types.js:384:28)
    at Object.fromObject (/Users/charlie/Code/fibos/transfer/node_modules/_fcbuffer@2.2.0@fcbuffer/lib/struct.js:151:34)
    at _callee2$ (/Users/charlie/Code/fibos/transfer/node_modules/_eosjs@16.0.2@eosjs/lib/write-api.js:657:38)
    at tryCatch (/Users/charlie/Code/fibos/transfer/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/Users/charlie/Code/fibos/transfer/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:296:22)
    at Generator.forEach.prototype.(anonymous function) [as next] (/Users/charlie/Code/fibos/transfer/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:114:21)

這個使用錯了 transfer 和 extransfer 函數。其中 transfer 函數表示的是與 EOS 主網兼容的轉帳方法,函數原型爲:

其中 transfer 函數表示的是與 EOS 主網兼容的轉帳方法,函數原型爲:

void transfer(account_name from, account_name to, asset quantity, string memo)

示例:

transfer('accountfrom', 'accountto', '1.0000 FO', 'memo field')

其中 extransfer 函數表示的是與 FIBOS 主網擴展的轉帳方法,該方法支持在 FIBOS 上發行的全部通證的轉帳,函數原型爲:

void extransfer(account_name from, account_name to, extended_asset quantity, string memo)

示例:

extransfer('accountfrom', 'accountto', '1.0000 FO@eosio', 'memo field')

其中,@ 字符後表示的是該通證的發行方,系統通證 FO 爲 FO@eosio,eosio 表示的是該通證是系統原生髮行的通證。

6. 後記

轉帳操做相關的內容就介紹完了。有什麼問題留言。也能夠在知乎上關注我:https://zhuanlan.zhihu.com/p/...

相關文章
相關標籤/搜索