原文:https://github.com/qtumproject/qtumjs-doc 译者:中山大学数学学院(珠海)林学渊 大二时给量子做的翻译,转载注明出处,谢谢
介绍
安装 qtumjs
npm install qtumjs
QtumJS是一个用于在Qtum区块链上开发DApp的JavaScript库。您可以使用此库来开发在浏览器中运行的前端UI以及在NodeJS中运行的后端脚本。
主要的类: 类 | 描述 ——— | ———– QtumRPCRaw | 使用 JSONRPC 1.0调用合约,直接访问
qtumd 的区块链 RPC 服务。 QtumRPC | QtumRPCRaw 的封装,提供像 JSONRPC 2.0 这样的接口。 Contract | 与智能合约交互的抽象层。使用 ABI encoding/decoding.QtumJS 使用 TypeScript 开发, 因此为所有 API 提供了健壮的类型定义。 我们建议使用 VSCode 来获得语言支持,例如类型提示和自动完成。
当然,你愿意的话也可以选择使用普通的 JavaScript 和记事本。
本文档是 QtumJS API 及其基本用法的参考文档。有关 QtumJS 的教程式介绍,查看: QtumBook - ERC20 With QtumJS.
运行 Qtum RPC
开发模式运行 qtumd:
docker run -it --rm \ --name myapp \ -v `pwd`:/dapp \ -p 3889:3889 \ hayeah/qtumportal
测试网络(testnet)运行 qtumd:
docker run -it --rm \ --name myapp \ -e "QTUM_NETWORK=testnet" \ -v `pwd`:/dapp \ -p 3889:3889 \ hayeah/qtumportal
QtumJS 依赖
qtumd 提供的访问 QTUM 区块链的 JSON-RPC 服务。更多细节请查看: QtumBook - Running QTUM.
默认 JSON-RPC 是 “qtum:test”,运行端口为 3889
ERC20 实例
import { Qtum,} from "qtumjs"const repoData = require("./solar.json")const qtum = new Qtum("http://qtum:test@localhost:3889", repoData)const myToken = qtum.contract("zeppelin-solidity/contracts/token/CappedToken.sol")async function transfer(fromAddr, toAddr, amount) { const tx = await myToken.send("transfer", [toAddr, amount], { senderAddress: fromAddr, }) console.log("transfer tx:", tx.txid) console.log(tx) await tx.confirm(3) console.log("transfer confirmed")}
假设
solar.json 包含已部署的合约,则可以使用 qtumjs 调用代币合约的方法来流通代币。一个实例 solar.json. 这个可以使用 solar 部署工具自动生成。
合约开发, 查看 Solar Smart Contract Deployment Tool.
为了充实教程, 查看 QtumBook - ERC20 With QtumJS.
Qtum
const repoData = require("./solar.json")const qtum = new Qtum("http://qtum:test@localhost:3889", repoData)
Qtum 是 qtumjs API 的一个对象. 它提供两个主要功能:- 对
qtumdRPC 服务的访问. 它是 QtumRPC 的子类.
- 实例化 Contract 对象的工厂方法, 用于与已部署的合约进行交互。
参数 | 类型 |
url | string |
qtumd RPC 服务的 URL | ㅤ |
repoData | |
关于 Solidity 合约的信息. | ㅤ |
repoData 包含所有已部署合约或库的 ABI 定义,以及它们的部署地址。这些信息用于实例化 Contract 实例。使用
Qtum 的工厂方法实例化的 Contract 对象能够解码所有在 repoData 里的事件类型. 但是手动构建的合约只能解码在其范围内定义的事件类型, 这也是 Solidity 编译器输出 ABI 定义的限制。建议使用 Qtum 来实例化
Contract 对象.contract
const myToken = qtum.contract("zeppelin-solidity/contracts/token/CappedToken.sol")
实例化这个合约使用了 这些 信息。
实例化
Contract 对象的工厂方法,使用了 repoData 中的 ABI 定义和地址。合约对象是使用一个事件 log 解码器来配置的,这个解码器能解码所有 repoData 中已知的事件类型。参数 | 类型 |
name | string |
作为 repoData.contracts map 的 key,用于获取合约信息。 | ㅤ |
rawCall
继承自 QtumRPC#rawcall
Contract
与智能合约交互的抽象层。
这比使用
QtumRPC 直接调用 RPC 的 sendcontract 和 calltocontract 方法更方便。它处理 ABI 编码,转换 JS 和 Solidity 值。- 有 API 用于确认交易。
- 有 API 用于调用合约方法,使用
call或send.
- 有 API 用于获取合约 log 事件。
构造函数
const rpc = new QtumRPC("http://qtum:test@localhost:3889")const myToken = new Contract(rpc, repo.contracts[ "zeppelin-solidity/contracts/token/CappedToken.sol"])
合约 信息 可以使用 solar. 生成
参数 | 类型 | 描述 |
rpc | QtumRPC | RPC 对象,用于与合约进行交互 |
info | 信息,用于部署合约 |
建议使用 Qtum#contract 而不是这个构造器。
call
async function totalSupply() { const result = await myToken.call("totalSupply") // supply is a BigNumber instance (see: bn.js) const supply = result.outputs[0] console.log("supply", supply.toNumber())}
实例输出:
{ address: 'a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3', executionResult: { gasUsed: 21689, excepted: 'None', newAddress: 'a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3', output: '00000000000000000000000000000000000000000000000000000000000036b0', codeDeposit: 0, gasRefunded: 0, depositSize: 0, gasForDeposit: 0 }, transactionReceipt: { stateRoot: '5a0d9cd5df18165c75755f4345ca81da94f9247c1c031171fd6e2ce1a368844c', gasUsed: 21689, bloom: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', log: [] }, outputs: [ <BN: 36b0> ] }
模拟 “mint” 调用:
const result = await myToken.call("mint", ["dcd32b87270aeb980333213da2549c9907e09e94", 1000])
运行结果:
{ "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "executionResult": { "gasUsed": 39306, "excepted": "None", "newAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "output": "0000000000000000000000000000000000000000000000000000000000000001", "codeDeposit": 0, "gasRefunded": 0, "depositSize": 0, "gasForDeposit": 0 }, "transactionReceipt": { "stateRoot": "9922edb770bd700a212427d3bc0764a9fed953a987952b2619b8a78dac7498aa", "gasUsed": 39306, "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000020000000000008000000000000000000000000000000000000000000000000020000000020000000000800000000000000400000000010000000000000000000000000000000000000000000000000000000000000000000000000000080000000080000000000000000000000000000000000000000000000000000000002010000000000000000000000000000000200000000000000000020000000000000000000000000000000000000000000000000020000000000000000", "log": [ { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8" }, { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8" } ] }, "outputs": [ true ], "logs": [ { "type": "Mint", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "amount": "3e8" }, { "type": "Transfer", "from": "0000000000000000000000000000000000000000", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "value": "3e8" } ]}
使用
callcontract 在你本地 qtumd 节点 “模拟” 执行合约方法。这是免费的,实际上并不修改区块链。这个免费。
参数 | 类型 |
method | string |
合约方法名 | ㅤ |
args | Array<any> |
调用方法的参数 | ㅤ |
opts | IContractCallRequestOptions |
调用配置项 | ㅤ |
@return | Promise<IContractCallResult> |
调用结果,带有 ABI 解码的输出 | ㅤ |
send
async function mint(toAddr, amount) { // Submit a `sendtocontract` transaction, invoking the `mint` method. const tx = await myToken.send("mint", [toAddr, amount]) console.log("tx:", tx) // Wait for 3 confirmations. The callback receives the // updated transaction info for each additional confirmation. // // Both arguments are optional. `await tx.confirm()` would do. const receipt = await tx.confirm(3, (updatedTx) => { console.log("new confirmation", updatedTx.txid, updatedTx.confirmations) }) console.log("tx receipt:", JSON.stringify(receipt, null, 2))}
实例输出:
mint tx: 858347704258506012f538b19b9702d636dc350bc25a7e60d404bf3d2c08efd9 { amount: 0, fee: -0.081064, confirmations: 0, trusted: true, txid: '858347704258506012f538b19b9702d636dc350bc25a7e60d404bf3d2c08efd9', walletconflicts: [], time: 1515475961, timereceived: 1515475961, 'bip125-replaceable': 'no', details: [ { account: '', category: 'send', amount: 0, vout: 0, fee: -0.081064, abandoned: false } ], hex: '0200000001006a977de70014fdc2546ed19a531326086c6c9631cb1c5352db5f09e147736b0100000049483045022100b4ca32770a9f42679c6d20b7ddb5feb160303fceafc2db0fedba18a22f0b643602203c2568eb689fd324e76a12f367552fe4cce36b29f8174738209f881959aadbab01feffffff02000000000000000063010403400d0301284440c10f19000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94000000 00000000000000000000000000000000000000000000000000000003e814a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3c2601e72902e0000001976a914dcd32b87270aeb980333213da2549c9907e09e9488ac212e0000', method: 'mint', confirm: [Function: confirm] }
回调打印 3 次,分别对应每次确认
new confirmation 858347704258506012f538b19b9702d636dc350bc25a7e60d404bf3d2c08efd9 1 new confirmation 858347704258506012f538b19b9702d636dc350bc25a7e60d404bf3d2c08efd9 2 new confirmation 858347704258506012f538b19b9702d636dc350bc25a7e60d404bf3d2c08efd9 3
确认后返回的交易收据:
{ "blockHash": "3b53ad132c26f9c30e5be9f664573428dad8b52e167becea4428d6903cb32740", "blockNumber": 13917, "transactionHash": "79338589bb75e1865be889142890a4e25d3b9dbd454ce3f3c2614587c85e2ed3", "transactionIndex": 1, "from": "dcd32b87270aeb980333213da2549c9907e09e94", "to": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "cumulativeGasUsed": 39306, "gasUsed": 39306, "contractAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "logs": [ { "type": "Mint", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "amount": "7d0" }, { "type": "Transfer", "from": "0000000000000000000000000000000000000000", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "value": "7d0" } ], "rawlogs": [ { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000007d0" }, { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000007d0" } ]}
创建一个交易,在网络全局执行合约方法,会改变区块链。
这要花费 gas.
对一个合约有 2 个异步步骤
- 你提交交易到网络
- 一旦提交,等待一个指定的确认数
成功确认后,返回带有ABI解码的事件日志的交易收据 (IContractSendReceipt)
参数 | 类型 |
method | string |
合约方法名 | ㅤ |
args | Array<any> |
所调用方法的参数 | ㅤ |
opts | |
可选 发送配置项 | ㅤ |
@return | Promise<IContractSendResult> |
调用结果, 带有 ABI 解码的输出 | ㅤ |
方法重载
如果没有歧义,使用方法名称来调用/发送方法。 如果相同方法名称具有多个定义,请使用方法签名来调用/发送方法。
方法名 foo 可能有多个定义:
function foo();function foo(int256 _a);function foo(uint256 _a, uint256 _b);function foo(int256 _a, int256 _b);
foo 方法有 0 个参数和有 1 个参数没有歧义。可以直接调用。
contract.call("foo")contract.call("foo", [1])
foo 方法带 2 个参数的有歧义,必须带完整方法签名:
contract.call("foo(uint256,uint256)", [1, 2])contract.call("foo(int256,int256)", [1, 2])
logs
async function getLogs(fromBlock=0, toBlock="latest") { const logs = await myToken.logs({ fromBlock, toBlock, minconf: 1, }) console.log(JSON.stringify(logs, null, 2))}
实例输出
{ "entries": [ { "blockHash": "369c6ded05c27ae7efc97964cce083b0ea9b8b950e67c51e52cb1bf898b9c415", "blockNumber": 12184, "transactionHash": "d1638a53f38fd68c5763e2eef9d86b9fc6ee7ea3f018dae7b1e385b4a9a78bc7", "transactionIndex": 2, "from": "dcd32b87270aeb980333213da2549c9907e09e94", "to": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "cumulativeGasUsed": 39306, "gasUsed": 39306, "contractAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8", "event": { "type": "Mint", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "amount": "3e8" } }, { "blockHash": "369c6ded05c27ae7efc97964cce083b0ea9b8b950e67c51e52cb1bf898b9c415", "blockNumber": 12184, "transactionHash": "d1638a53f38fd68c5763e2eef9d86b9fc6ee7ea3f018dae7b1e385b4a9a78bc7", "transactionIndex": 2, "from": "dcd32b87270aeb980333213da2549c9907e09e94", "to": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "cumulativeGasUsed": 39306, "gasUsed": 39306, "contractAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8", "event": { "type": "Transfer", "from": "0000000000000000000000000000000000000000", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "value": "3e8" } } ], "count": 2, "nextblock": 12185}
获取由合约生成的 Solidity 事件日志 。
通过指定
fromBlock 和 toBlock,可以将事件日志查询限制块号范围。 例如,可以查询块 1000 到 1500 之间的事件日志。此外,你可以使用
minconf 指定事件日志之前确认的最小数量作为结果返回。参数 | 类型 |
opts | |
事件日志查询参数 | ㅤ |
@return | Promise<IContractEventLogs> |
日志查询结果,带有 ABI 解码的输出 | ㅤ |
onLogs
myToken.onLog((entry) => { console.log(entry)}, { minconf: 1 })
订阅合约新事件。每次收到新事件时都会调用回调。默认情况下,
onLog 监听来自区块链顶端的日志。 使用 fromBlock 也可以接收较早的事件。参数 | 类型 |
callback | (entry: IContractEventLog) => void |
opts | |
事件日志查询参数 | ㅤ |
logEmitter
this.emitter = myToken.logEmitter({ minconf: 1 })this.emitter.on("Mint", (event) => { // ...})this.emitter.on("Transfer", (event) => { // ...})this.emitter.on("?", (event) => { // all un-decodeable events})
使用 EventsEmitter 接口订阅合约新事件。发出的事件是 IContractEventLog 对象。
Solidity 事件名作为发出的事件名使用。
缺失 ABI 定义的事件 (即不能解析) 会发送 “?”.
参数 | 类型 |
opts | |
事件日志查询参数 | ㅤ |
receipt
const txid = "62fecfd27d71ddb260ac48c73c8f0f87e96d0b3a598ed2c2251caa4e6f9a9d97"const receipt = await qrcToken.receipt(txid)console.log(JSON.stringify(receipt, null, 2))
实例输出
{ "blockHash": "af37cb8d9905521542243005fadc9f18c1498c9823e35fa277ea1c37174c289a", "blockNumber": 83981, "transactionHash": "62fecfd27d71ddb260ac48c73c8f0f87e96d0b3a598ed2c2251caa4e6f9a9d97", "transactionIndex": 28, "from": "57142e3bcf000f28890b5d979afc7ea90204e1de", "to": "49665919e437a4bedb92faa45ed33ebb5a33ee63", "cumulativeGasUsed": 37029, "gasUsed": 37029, "contractAddress": "49665919e437a4bedb92faa45ed33ebb5a33ee63", "logs": [ { "type": "Transfer", "from": "57142e3bcf000f28890b5d979afc7ea90204e1de", "to": "c0ed80283c53c300c31c2bda6eca841e53cb6a21", "value": "1ba5add5700" } ], "rawlogs": [ { "address": "49665919e437a4bedb92faa45ed33ebb5a33ee63", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "00000000000000000000000057142e3bcf000f28890b5d979afc7ea90204e1de", "000000000000000000000000c0ed80283c53c300c31c2bda6eca841e53cb6a21" ], "data": "000000000000000000000000000000000000000000000000000001ba5add5700" } ]}
获取已被网络接受的交易收据。 如果交易尚未确认,则返回空值。
交易事件日志是 ABI 编码
参数 | 类型 |
txid | string |
交易 ID | ㅤ |
@return | Promise<IContractSendReceipt> |
交易收据, 带有事件日志. | ㅤ |
QtumRPC
const rpc = new QtumRPC('http://qtum:test@localhost:3889');
这是一个用于直接访问
qtumd RPC API 的 JSON-RPC 客户端。它不会为你处理任何 ABI 编码或解码。有需要的话你可以把 RPC 用户名和密码包含到 URL 里。在例子中,用户名是
qtum ,密码是 test.QtumRPC类有一些在合约抽象内部使用的未公开的方法。 考虑将来可能会发生变化的任何未经证实的不受支持的内容。 现在,rawCall是唯一的公共API。 注意:
QtumRPC 类有一些没文档的 public 方法在 Contract 抽象层内部使用到了. 你要考虑到之后可能不支持的无文档的内容. 现在 rawCall 是唯一发布的 API.参数 | 类型 |
url | string |
qtumd RPC 服务的 URL | ㅤ |
rawCall
调用 getinfo RPC 方法以获取 Qutm 区块链的基本信息:
const info = await rpc.rawCall("getinfo")console.log(info)
getinfo 的输出:
{ version: 141300, protocolversion: 70016, walletversion: 130000, balance: 0, stake: 0, blocks: 85685, timeoffset: 0, connections: 8, proxy: '', difficulty: { 'proof-of-work': 0.0000152587890625, 'proof-of-stake': 5207642.8878753 }, testnet: false, moneysupply: 100322740, keypoololdest: 1513325658, keypoolsize: 100, paytxfee: 0, relayfee: 0.004, errors: '' }
发起一个 JSON-RPC 1.0 方法调用, 返回调用结果. 如果 JSON API 返回不是 200 HTTP 结果,则抛出错误。
使用 try...catch 处理错误:
async function main() { try { const result = await rpc.rawCall("unknown-method-hohoho") } catch (err) { console.log("err", err) }}
All RPC 方法
qtumd 支持的所有 RPC 方法 .
== Blockchain == callcontract "address" "data" ( address ) getaccountinfo "address" getbestblockhash getblock "blockhash" ( verbose ) getblockchaininfo getblockcount getblockhash height getblockheader "hash" ( verbose ) getchaintips getdifficulty getmempoolancestors txid (verbose) getmempooldescendants txid (verbose) getmempoolentry txid getmempoolinfo getrawmempool ( verbose ) getstorage "address" gettransactionreceipt "hash" gettxout "txid" n ( include_mempool ) gettxoutproof ["txid",...] ( blockhash ) gettxoutsetinfo listcontracts (start maxDisplay) preciousblock "blockhash" pruneblockchain searchlogs <fromBlock> <toBlock> (address) (topics) verifychain ( checklevel nblocks ) verifytxoutproof "proof" waitforlogs (fromBlock) (toBlock) (filter) (minconf) == Control == getinfo getmemoryinfo help ( "command" ) stop == Generating == generate nblocks ( maxtries ) generatetoaddress nblocks address (maxtries) == Mining == getblocktemplate ( TemplateRequest ) getmininginfo getnetworkhashps ( nblocks height ) getstakinginfo getsubsidy [nTarget] prioritisetransaction <txid> <priority delta> <fee delta> submitblock "hexdata" ( "jsonparametersobject" ) == Network == addnode "node" "add|remove|onetry" clearbanned disconnectnode "node" getaddednodeinfo ( "node" ) getconnectioncount getnettotals getnetworkinfo getpeerinfo listbanned ping setban "subnet" "add|remove" (bantime) (absolute) setnetworkactive true|false == Rawtransactions == createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) decoderawtransaction "hexstring" decodescript "hexstring" fromhexaddress "hexaddress" fundrawtransaction "hexstring" ( options ) gethexaddress "address" getrawtransaction "txid" ( verbose ) sendrawtransaction "hexstring" ( allowhighfees ) signrawtransaction "hexstring" ( [{"txid":"id","vout":n,"scriptPubKey":"hex","redeemScript":"hex"},...] ["privatekey1",...] sighashtype ) == Util == createmultisig nrequired ["key",...] estimatefee nblocks estimatepriority nblocks estimatesmartfee nblocks estimatesmartpriority nblocks signmessagewithprivkey "privkey" "message" validateaddress "address" verifymessage "address" "signature" "message" == Wallet == abandontransaction "txid" addmultisigaddress nrequired ["key",...] ( "account" ) addwitnessaddress "address" backupwallet "destination" bumpfee "txid" ( options ) createcontract "bytecode" (gaslimit gasprice "senderaddress" broadcast) dumpprivkey "address" dumpwallet "filename" encryptwallet "passphrase" getaccount "address" getaccountaddress "account" getaddressesbyaccount "account" getbalance ( "account" minconf include_watchonly ) getnewaddress ( "account" ) getrawchangeaddress getreceivedbyaccount "account" ( minconf ) getreceivedbyaddress "address" ( minconf ) gettransaction "txid" ( include_watchonly ) (waitconf) getunconfirmedbalance getwalletinfo importaddress "address" ( "label" rescan p2sh ) importmulti "requests" "options" importprivkey "qtum" ( "label" ) ( rescan ) importprunedfunds importpubkey "pubkey" ( "label" rescan ) importwallet "filename" keypoolrefill ( newsize ) listaccounts ( minconf include_watchonly) listaddressgroupings listlockunspent listreceivedbyaccount ( minconf include_empty include_watchonly) listreceivedbyaddress ( minconf include_empty include_watchonly) listsinceblock ( "blockhash" target_confirmations include_watchonly) listtransactions ( "account" count skip include_watchonly) listunspent ( minconf maxconf ["addresses",...] [include_unsafe] ) lockunspent unlock ([{"txid":"txid","vout":n},...]) move "fromaccount" "toaccount" amount ( minconf "comment" ) removeprunedfunds "txid" reservebalance [<reserve> [amount]] sendfrom "fromaccount" "toaddress" amount ( minconf "comment" "comment_to" ) sendmany "fromaccount" {"address":amount,...} ( minconf "comment" ["address",...] ) sendmanywithdupes "fromaccount" {"address":amount,...} ( minconf "comment" ["address",...] ) sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount ) sendtocontract "contractaddress" "data" (amount gaslimit gasprice senderaddress broadcast) setaccount "address" "account" settxfee amount signmessage "address" "message"
实例: getblockcount
返回最长的区块链的块数。
const result = await rpc.rawCall("getblockcount")
结果
85687
实例: getnewaddress
返回接收付款的新 Qtum 地址。可能对要为用户生成存款地址的交易所有用。
const result = await rpc.rawCall("getnewaddress")
结果
QSnrDTj4UNcRwKdhY8sUZEd74VzwqeAddW
实例: fromhexaddress
把一个 base58 pubkeyhash 地址转化成 16 进制地址用于智能合约。
const result = await rpc.rawCall("gethexaddress", ["QSnrDTj4UNcRwKdhY8sUZEd74VzwqeAddW"])
结果
43debdac95a0eaa4ff92d6b873944a4d92beae59
实例: gettransactionreceipt
获得确认交易的收据。
const txid = "62fecfd27d71ddb260ac48c73c8f0f87e96d0b3a598ed2c2251caa4e6f9a9d97"const result = await rpc.rawCall("gettransactionreceipt", [txid])
结果
[ { "blockHash": "af37cb8d9905521542243005fadc9f18c1498c9823e35fa277ea1c37174c289a", "blockNumber": 83981, "transactionHash": "62fecfd27d71ddb260ac48c73c8f0f87e96d0b3a598ed2c2251caa4e6f9a9d97", "transactionIndex": 28, "from": "57142e3bcf000f28890b5d979afc7ea90204e1de", "to": "49665919e437a4bedb92faa45ed33ebb5a33ee63", "cumulativeGasUsed": 37029, "gasUsed": 37029, "contractAddress": "49665919e437a4bedb92faa45ed33ebb5a33ee63", "log": [ { "address": "49665919e437a4bedb92faa45ed33ebb5a33ee63", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "00000000000000000000000057142e3bcf000f28890b5d979afc7ea90204e1de", "000000000000000000000000c0ed80283c53c300c31c2bda6eca841e53cb6a21" ], "data": "000000000000000000000000000000000000000000000000000001ba5add5700" } ] }]
类型词典
IContractInfo
export interface IContractInfo { /** * 合约的 ABI 定义, solc 生成. */ abi: IABIMethod[] /** * 合约地址 */ address: string /** * 合约所有者的地址 */ sender?: string}
与部署合约交互所需的最少部署信息。
IContractCallResult
调用一个合约方法的返回结果,带有解码的输出和日志。
export interface IContractCallResult extends IRPCCallContractResult { /** * ABI 解码的输出 */ outputs: any[] /** * ABI 解码的日志 */ logs: Array<IDecodedSolidityEvent | null>}export interface IRPCCallContractResult { address: string executionResult: IExecutionResult, transactionReceipt: { stateRoot: string, gasUsed: string, bloom: string, log: any[], }}export interface IExecutionResult { gasUsed: number, excepted: string, newAddress: string, output: string, codeDeposit: number, gasRefunded: number, depositSize: number, gasForDeposit: number,}
实例:
{ "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "executionResult": { "gasUsed": 39306, "excepted": "None", "newAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "output": "0000000000000000000000000000000000000000000000000000000000000001", "codeDeposit": 0, "gasRefunded": 0, "depositSize": 0, "gasForDeposit": 0 }, "transactionReceipt": { "stateRoot": "9922edb770bd700a212427d3bc0764a9fed953a987952b2619b8a78dac7498aa", "gasUsed": 39306, "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000020000000000008000000000000000000000000000000000000000000000000020000000020000000000800000000000000400000000010000000000000000000000000000000000000000000000000000000000000000000000000000080000000080000000000000000000000000000000000000000000000000000000002010000000000000000000000000000000200000000000000000020000000000000000000000000000000000000000000000000020000000000000000", "log": [ { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8" }, { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8" } ] }, "outputs": [ true ], "logs": [ { "type": "Mint", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "amount": "3e8" }, { "type": "Transfer", "from": "0000000000000000000000000000000000000000", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "value": "3e8" } ]}
Contract#call 的返回类型.IContractSendRequestOptions
Contract#send 的配置项
/** * `send` 合约方法的配置项. */export interface IContractSendRequestOptions { /** * 要发送的 QTUM 数. 例如 0.1, 默认: 0 */ amount?: number | string /** * gasLimit, 默认: 200000, 最大: 40000000 */ gasLimit?: number /** * 每 gas 的 Qtum 价格, 默认: 0.00000001, 最小:0.00000001 */ gasPrice?: number | string /** * 发送者的 quantum 地址 */ senderAddress?: string}
IContractSendResult
const tx = await contract.send(method, args)await tx.confirm(3, (updatedTx, receipt) => { /// ...})
返回 Contract#send 的值。
confirm 方法用来等待交易确认。confirm 方法的参数:参数 | 类型 |
n | number |
可选 须等待的确认数 | ㅤ |
callback | IContractSendConfirmationHandler |
可选 回调函数,每次确认都会调用 | ㅤ |
回调值为:
参数 | 类型 |
updatedTx | IRPCGetTransactionResult |
关于提交给网络的交易的基本信息 | ㅤ |
receipt | IContractSendReceipt |
关于已确认交易的其他信息 | ㅤ |
参考
IRPCGetTransactionResult
export interface IRPCGetTransactionResult { amount: number, fee: number, confirmations: number, blockhash: string, blockindex: number, blocktime: number, txid: string, walletconflicts: any[], time: number, timereceived: number, "bip125-replaceable": "no" | "yes" | "unknown", details: any[] hex: string,}
关于提交给网络的交易的基本信息。
IContractSendReceipt
Contract#send 的合约收据, 带有解码的事件日志
export interface IContractSendReceipt extends IRPCGetTransactionReceiptBase { /** * 使用 ABI 解码的日志 */ logs: IDecodedLog[], /** * 未解码的日志 */ rawlogs: ITransactionLog[],}/** * 解码的 Solidity 事件日志 */export interface IDecodedLog { /** * 事件日志名称 */ type: string /** * 键值映射作为事件日志参数 */ [key: string]: any}
实例
{ "blockHash": "3b53ad132c26f9c30e5be9f664573428dad8b52e167becea4428d6903cb32740", "blockNumber": 13917, "transactionHash": "79338589bb75e1865be889142890a4e25d3b9dbd454ce3f3c2614587c85e2ed3", "transactionIndex": 1, "from": "dcd32b87270aeb980333213da2549c9907e09e94", "to": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "cumulativeGasUsed": 39306, "gasUsed": 39306, "contractAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "logs": [ { "type": "Mint", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "amount": "7d0" }, { "type": "Transfer", "from": "0000000000000000000000000000000000000000", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "value": "7d0" } ], "rawlogs": [ { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000007d0" }, { "address": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000007d0" } ]}
参考
IRPCWaitForLogsRequest
export interface IRPCWaitForLogsRequest { /** * 查找日志的开始块号。 */ fromBlock?: number | "latest", /** * 查找日志的停止块号. 如果是 null, 会无限期等待 */ toBlock?: number | "latest", /** * 过滤日志的条件。 地址和主题分别指定为十六进制字符串数组 */ filter?: ILogFilter, /** * 日志返回前的最少确认数 */ minconf?: number,}
IContractEventLogs
/** * 查询合约事件日志的结果。 */export interface IContractEventLogs { /** * 事件日志, ABI 解码. */ entries: IContractEventLog[] /** * 返回的事件日志数 */ count: number /** * 要开始查询新事件日志的块号 */ nextblock: number}
查询合约事件日志的结果。
IContractEventLog
一条解码的合约事件日志
export interface IContractLogEntry extends ILogEntry { /** * Solidity 事件, ABI 解码. 如果没有找到 ABI 定义,为 Null */ event?: ISolidityEvent}/** * qtumd 返回的原始日志数据,不是 ABI 解码 */export interface ILogEntry extends IRPCGetTransactionReceiptBase { /** * EVM 日志主题 */ topics: string[] /** * EVM 日志数据, 十六进制字符串 */ data: string}/** * qtumd 返回的交易收据 */export interface IRPCGetTransactionReceiptBase { blockHash: string blockNumber: number transactionHash: string transactionIndex: number from: string to: string cumulativeGasUsed: number gasUsed: number contractAddress: string}
实例
{ "blockHash": "369c6ded05c27ae7efc97964cce083b0ea9b8b950e67c51e52cb1bf898b9c415", "blockNumber": 12184, "transactionHash": "d1638a53f38fd68c5763e2eef9d86b9fc6ee7ea3f018dae7b1e385b4a9a78bc7", "transactionIndex": 2, "from": "dcd32b87270aeb980333213da2549c9907e09e94", "to": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "cumulativeGasUsed": 39306, "gasUsed": 39306, "contractAddress": "a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3", "topics": [ "0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", "000000000000000000000000dcd32b87270aeb980333213da2549c9907e09e94" ], "data": "00000000000000000000000000000000000000000000000000000000000003e8", "event": { "type": "Mint", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "amount": "3e8" }}
IDecodedSolidityEvent
/** * 一个解码的 Solidity 事件日志 */export interface IDecodedSolidityEvent { /** * 事件名称 */ type: string /** * 键值映射作为事件日志参数 */ [key: string]: any}
Example
{ "type": "Transfer", "from": "0000000000000000000000000000000000000000", "to": "dcd32b87270aeb980333213da2549c9907e09e94", "value": "3e8"}
解码的 Solidity 事件日志。 事件参数存储在键值映射中。
IRPCGetTransactionReceiptBase
网络接受的交易收据。它由
gettransactionreceipt RPC 调用返回。export interface IRPCGetTransactionReceiptBase { blockHash: string blockNumber: number transactionHash: string transactionIndex: number from: string to: string cumulativeGasUsed: number gasUsed: number contractAddress: string}
IContractsRepoData
合约相关信息
export interface IContractsRepoData { /** * 部署合约的相关信息 */ contracts: { [key: string]: IContractInfo, }, /** * 部署库的相关信息 */ libraries: { [key: string]: IContractInfo, } /** * 部署合约/库引用的合约信息,但未部署 */ related: { [key: string]: { abi: IABIMethod[], }, }}/** * 与部署合约进行交互所需的最少部署信息。 */export interface IContractInfo { /** * 合约的 ABI 定义, solc 生成. */ abi: IABIMethod[] /** * 合约地址 */ address: string /** * 合约所有者的地址 */ sender?: string}export interface IABIMethod { name: string, type: string, payable: boolean, inputs: IABIInput[], outputs: IABIOutput[], constant: boolean, anonymous: boolean,}
可以使用开发工具 solar 自动生成。
样例 solar.json.
