本文以 0.2.27 版本的 JS SDK 為例,通過示例闡述如何快速使用 JS SDK 進行合約開發。
JS SDK 0.3.8 與 0.2.27 版本保持兼容,本快速開始同時適用于以上兩個版本。
準備環境
安裝 SDK
從 Node.js 官網 下載并安裝 Node.js(推薦使用v10以上v16以下版本)。
安裝 JS SDK。下載 JS SDK V0.2.27 安裝包 至項目目錄,然后在項目目錄中安裝。
npm i alipay-mychain-0.2.27.tgz --save
準備 SSL 連接文件
要與 BaaS 平臺建立 SSL 連接,需準備三個證書文件:ca.crt
、client.key
、client.crt
。
如果您尚未在合約鏈申請證書,可按照 試用合約體驗鏈 的操作說明去生成和申請證書相關文件。
文件 | 說明 | 來源 |
ca.crt | 合約鏈的認證 CA,客戶端用來驗證合約鏈服務身份 | 通過 BaaS 平臺下載。 |
client.key | RSA 密鑰 | 通過 BaaS 提供的 密鑰生成工具 生成。 |
client.crt | RSA 證書,與 | 使用 BaaS 提供的 密鑰生成工具 生成證書請求文件 |
準備合約鏈的賬戶
在合約鏈上提交交易時,需要使用一個已經在鏈上存在的賬戶,JS SDK 需要使用賬戶的 賬戶名稱 和 私鑰文件。
賬戶可通過 BaaS 平臺申請創建。參考 試用合約體驗鏈 的過程,需要填寫創建的賬戶名稱、賬戶公鑰和恢復公鑰,其中與賬戶公鑰對應的 user.key
文件就是賬戶的私鑰文件,對此私鑰文件進行轉換,方便在 JS SDK 中使用。
openssl ec -in user.key -passin pass:${key_password} -passout pass:${key_password} -aes256 -out user.pem
將 ${key_password} 替換為私鑰密碼。
獲取鏈節點 IP 和端口號
要與合約鏈交互,您需要獲取鏈節點的 IP 地址和端口號。在 BaaS 平臺,通過查看目標合約鏈詳情,在區塊瀏覽器中查看節點詳情,可獲取鏈節點的 IP 地址和端口號。
使用 JS SDK
快速創建一個訪問區塊鏈的實例 chain
,并使用 QueryLastBlock
驗證該實例與區塊鏈節點的連接狀況。
const Chain = require("@alipay/mychain/index.node") //在 node 環境使用 TLS 協議
const fs = require("fs")
const accountKey = fs.readFileSync("./certs/user.pem", { encoding: "utf8" })
const accountPassword = "123abc" //需要替換為自定義的 user.pem 密碼
const keyInfo = Chain.utils.getKeyInfo(accountKey, accountPassword)
//可打印私鑰和公鑰,使用 16 進制
//console.log('private key:', keyInfo.privateKey.toString('hex'))
//console.log('public key:', keyInfo.publicKey.toString('hex'))
const passphrase = "123abc" //需要替換為自定義的 client.key 密碼
//配置選項
let opt = {
host: '127.0.0.1', //目標區塊鏈網絡節點的 IP
port: 18130, //端口號
timeout: 30000, //連接超時時間配置
cert: fs.readFileSync("./certs/client.crt", { encoding: "utf8" }),
ca: fs.readFileSync("./certs/ca.crt", { encoding: "utf8" }),
key: fs.readFileSync("./certs/client.key", { encoding: "utf8" }),
userPublicKey: keyInfo.publicKey,
userPrivateKey: keyInfo.privateKey,
userRecoverPublicKey: keyInfo.publicKey,
userRecoverPrivateKey: keyInfo.privateKey,
passphrase: passphrase
}
//初始化一個連接實例
const chain = Chain(opt)
//調用 API 查詢最新的一個區塊數據
chain.ctr.QueryLastBlock({}, (err, data) => {
console.log('raw data:', data) //區塊結構數據
console.log('block hash:', data.block.block_header.hash) //區塊哈希
console.log('block number:', data.block.block_header.block_number) //區塊高度
})
成功運行結果參考:
raw data: { msg_type: 58,
sequence: 1,
return_code: 0,
group_id: '0x0000000000000000000000000000000000000000',
block:
{ block_header:
{ hash:
'0xe99d8958a45e8c87a7b10efc259828f06fe083995be52997f5d310f2b6d073a6',
version: 2,
block_number: 84265,
parent_hash:
'0x918b263a8e6c6fff594b89570970ef4bef24cf93aeed5347f7b250b070857c4b',
transaction_root:
'0x0000000000000000000000000000000000000000000000000000000000000000',
receipt_root:
'0x0000000000000000000000000000000000000000000000000000000000000000',
state_root:
'0x9f71cb9ce960e5637bad6da5be8daa2d7e557942208f241a60589b2de98e6c71',
gas_used: 0,
timestamp: 1547382477852,
log_bloom:
'0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' },
block_body:
{ transaction_list: [],
receipt_list: [],
consensus_proof:
'0xf8f2f8c9b8419746989382c1613c6c3ce98bf79ac92a8d69952c22f4064194869c53b4075d517cfc98eda861212687e49b186c08d196770bd356762fa2a88d0288c0556f271a01b84138a97446a75c76a31d24880c343407bd7bc24608685c494240ac603cad62201a01a423718661b24e517ee6f6b2fee6d356b57833305860700cca81b0238f870400b841eaf508392d9098a3e7fb46f6f7aa4b53311e5a0d13e300d02025af7453ea130a6c27407c1da254578cae80ed498d4807587883f837c1716b0be8ae02cf955d6000e61e83014929a0e200d8bee723d820022d5c5a1f8fe6b521c0a4fff0b5ec03a7c6061276d68b58' } },
api: 'QueryLastBlock' }
block hash: 0xe99d8958a45e8c87a7b10efc259828f06fe083995be52997f5d310f2b6d073a6
block number: 84265
運行結果示例中包含字段 return_code,此字段結果為 0,表示執行成功,否則其值為錯誤碼。后文介紹的交易回執(receipt)中 result 字段也是類似含義,詳細錯誤碼信息參見合約鏈錯誤碼。
JS SDK 引用說明
不同運行環境下, JS SDK 的引用方式稍有不同:
Node 環境:
const Chain = require("@alipay/mychain/index.node")
Web 環境:
const Chain = require("@alipay/mychain")
配置項說明
在初始化與區塊鏈連接的實例之前,可進行選項配置,各配置項的具體說明如下。
如無特別說明,配置項的數據類型默認為 string 類型。 配置項中配置了賬戶相關的 Key 信息,包括賬戶公私鑰、賬戶恢復公私鑰。鏈的連接實例默認使用配置項中的賬戶 Key 信息進行交易簽名。如果要切換賬戶,需要重新配置賬戶 Key 相關選項。詳情參見創建賬戶中切換賬戶配置的使用示例。
配置項 | 必填 | 配置說明 | 示例值 |
host | true | 區塊鏈節點的 IP 或者主機名。使用 TLS 時為 IP 地址;使用 HTTPS 時為主機名。 |
|
port | true | 區塊鏈節點開放連接的端口號,類型為 number。 | 18130 |
clients | false | 可設置多個 | [{host:’127.0.0.1’,port:18130}, {host:’127.0.0.2’,port:18130}] |
timeout | true | 與區塊鏈節點連接的超時時間配置,單位毫秒,類型為 number。 | 30000 |
ca | true | 目標合約鏈的根證書。 | 在 BaaS 平臺申請通過后下載,詳情參考 試用合約體驗鏈 |
cert | true | 客戶端證書文件。 | 在 BaaS 平臺申請通過后下載,詳情參考 試用合約體驗鏈 |
key | true | 客戶端生成的私鑰文件,用于生成證書請求文件,進而申請證書。 | |
userPublicKey | true | 賬戶公鑰,字符串內容為 16 進制。 |
|
userPrivateKey | true | 賬戶私鑰,字符串內容為 16 進制。 |
|
userRecoverPublicKey | true | 賬戶恢復公鑰,字符串內容為 16 進制。 |
|
userRecoverPrivateKey | true | 賬戶恢復私鑰,字符串內容為 16 進制。 |
|
passphrase | true | TLS 或 HTTPS 鏈接的 | 123abc |
checkServerIdentity | false | 針對 TLS 協議的配置,類型為 boolean,含義為是否啟用對服務端 hostname 的檢查,即對比服務端證書的 | false |
tx_querycount | false | 對于交易類型,提交交易后會調用 | 5 |
tx_querytime | false | 對于交易類型,提交交易后會調用 | 200 |