@salaku/js-sdk v1.3.1
js-sdk
安装
npm install --save @salaku/js-sdk
基本使用
常量
const tdsSDK = require('@salaku/js-sdk')
console.log(tdsSDK.constants)
选择加密算法(全局)
const tdsSDK = require('@salaku/js-sdk')
tdsSDK.setHash('sm3') // keccak-256 sha3-256
tdsSDK.setEC('sm2') // ed25519
事务签名
const tdsSDK = require('@salaku/js-sdk')
const tx = {
"version" : 1634693120,
"type" : 0,
"createdAt" : 1596091121,
"nonce" : 223814,
"from" : "",
"gasPrice" : 0,
"amount" : 20,
"payload" : "02b507fe1afd0cc7a525488292beadbe9f143784de44f8bc1c991636509fd50936",
"to" : "9cbf30db111483e4b84e77ca0e39378fd7605e1b",
}
tdsSDK.sign(tx, 'f00df601a78147ffe0b84de1dffbebed2a6ea965becd5d0bd7faf54f1f29c6b5')
console.log(tx.signature)
计算事务哈希值
const tdsSDK = require('@salaku/js-sdk')
const tx = tdsSDK.Transaction.clone({
"version" : 1634693120,
"type" : 0,
"createdAt" : 1596091121,
"nonce" : 223814,
"from" : "",
"gasPrice" : 0,
"amount" : 20,
"payload" : "02b507fe1afd0cc7a525488292beadbe9f143784de44f8bc1c991636509fd50936",
"to" : "9cbf30db111483e4b84e77ca0e39378fd7605e1b",
})
console.log(tx.getHash())
公钥转地址
const tdsSDK = require('@salaku/js-sdk')
const pk = '02a4d7ca616e70897b7874460da1aab58b56e54c200a08e52a04c69df26b138859' // 公钥
console.log(tdsSDK.publicKey2Address(pk))
生成随机的私钥
const tdsSDK = require('@salaku/js-sdk')
const sk = tdsSDK.generatePrivateKey() // 私钥
console.log(sk)
私钥转公钥
const tdsSDK = require('@salaku/js-sdk')
const sk = 'f00df601a78147ffe0b84de1dffbebed2a6ea965becd5d0bd7faf54f1f29c6b5' // 私钥
console.log(tdsSDK.privateKey2PublicKey(sk))
计算合约地址
const tdsSDK = require('@salaku/js-sdk')
const pk = '02a4d7ca616e70897b7874460da1aab58b56e54c200a08e52a04c69df26b138859' // 公钥
const addr = tdsSDK.publicKey2Address(pk) // 合约构造者的地址
const nonce = '100' // nonce
console.log(tdsSDK.getContractAddress(addr, nonce))
编译 assembly script 合约(异步),需要 node 环境
const tdsSDK = require('@salaku/js-sdk')
const src = 'index.ts'
tdsSDK.compileContract(src)
.then(buf => console.log('buf length ' + buf.length))
生成 assembly script 合约 abi
const fs = require('fs')
tdsSDK.compileABI(fs.readFileSync('assembly/coin.ts'))
使用事务构造器 TransactionBuilder
const sk = 'f00df601a78147ffe0b84de1dffbebed2a6ea965becd5d0bd7faf54f1f29c6b5' // 私钥
const builder = new tdsSDK.TransactionBuilder(tdsSDK.constants.POA_VERSION, sk, /* gas limit */ 0, /* gas price */ 0)
sk 私钥选填,如果不填私钥,事务的 from 为空,而且事务不会被签名 如果 builder 的 nonce 为0,则构造好的事务不会被签名,如果 builder 的 nonce 不为0,则构造出的事务都是已经签名过的事务,且每构造一个事务 builder 的 nonce 会自增 1
构造转账事务
const tx = builder.buildTransfer(1000, '****address****')
构造 POA 加入请求事务
const tx = builder.buildAuthJoin(constants.PEER_AUTHENTICATION_ADDR)
tx.nonce = 1
builder.sign(tx)
构造 POA 同意请求事务
const tx = builder.buildAuthApprove(constants.PEER_AUTHENTICATION_ADDR, '***同意的地址***')
构造 POA 退出事务
const tx = builder.buildAuthExit(constants.PEER_AUTHENTICATION_ADDR)
构造 POS 投票事务
const tx = builder.buildVote(1000, '***address***')
构造 POS 取消投票事务
const tx = builder.buildCancelVote('***transaction hash***')
RPC 工具类
const rpc = new tdsSDK.RPC('localhost', 7010) // 连接 http, ws
const secureRPC = new tdsSDK.RPC('localhost', 443, true) // 连接 https, wss
查看账户
const pk = '02a4d7ca616e70897b7874460da1aab58b56e54c200a08e52a04c69df26b138859' // 公钥或者地址
rpc.getAccount(pk)
.then(console.log)
获取 nonce
const pk = '02a4d7ca616e70897b7874460da1aab58b56e54c200a08e52a04c69df26b138859' // 公钥
rpc.getNonce(pk)
.then(nonce => console.log(`nonce = ${nonce}`))
发送事务(异步)
const tx = tdsSDK.Transaction.clone({
"version" : 1634693120,
"type" : 0,
"createdAt" : 1596091121,
"nonce" : 223814,
"from" : "",
"gasPrice" : 0,
"amount" : 20,
"payload" : "02b507fe1afd0cc7a525488292beadbe9f143784de44f8bc1c991636509fd50936",
"to" : "9cbf30db111483e4b84e77ca0e39378fd7605e1b",
})
rpc.sendTransaction(tx)
.then(() => console.log('success'))
.catch(console.error)
发送事务并等待事务进入区块
const tx = tdsSDK.Transaction.clone({
"version" : 1634693120,
"type" : 0,
"createdAt" : 1596091121,
"nonce" : 223814,
"from" : "",
"gasPrice" : 0,
"amount" : 20,
"payload" : "02b507fe1afd0cc7a525488292beadbe9f143784de44f8bc1c991636509fd50936",
"to" : "9cbf30db111483e4b84e77ca0e39378fd7605e1b",
})
rpc.sendObserve(tx)
.then(console.log) // 这里会打印出事务所在的区块以及gas消耗、手续费等信息
.catch(console.error)
查看区块(异步)
rpc.getBlock(1) // 可以填区块哈希值或者区块高度
.then(console.log)
.catch(console.error)
查看区块头(异步)
rpc.getHeader(1) // 可以填区块哈希值或者区块高度
.then(console.log)
.catch(console.error)
查看事务(异步)
rpc.getTransaction('****') // 填写事务哈希
.then(console.log)
.catch(console.error)
// 事务的 confrims 字段 -1 表示在内存池中
// 0 或者以上表示被确认, confirms 表示确认数量
// 如出现异常,表示事务不存在
查看 POA 的 P2P 网络申请列表
rpc.getAuthPending(constants.PEER_AUTHENTICATION_ADDR)
.then(console.log)
.catch(console.error)
查看 POA 的 P2P 网络已加入列表
rpc.getAuthNodes(constants.PEER_AUTHENTICATION_ADDR)
.then(console.log)
.catch(console.error)
查看 POS 投票列表
rpc.getPoSNodeInfos()
.then(console.log)
.catch(console.error)
POS 根据事务哈希查看投票
rpc.getPoSVoteInfo('**txhash**')
.then(console.log)
.catch(console.error)
撤回投票
撤回投票事务的 from 必须是投票事务的 from
const tx = builder.buildCancelVote('c2458cad4c838b81b49500d9268b352b03cd1b78423c113f1b11f41c4ce13657')
智能合约编译部署和调用,假设入口文件如下
/**
* erc 20 example in assembly script
*/
export { __change_t, __malloc, __peek } from './node_modules/@salaku/js-sdk/lib' // 区块链应用程序接口
import { Util, U256, Globals, ABI_DATA_TYPE } from './node_modules/@salaku/js-sdk/lib'
import { Store } from './node_modules/@salaku/js-sdk/lib'
import { Context, Address } from './node_modules/@salaku/js-sdk/lib'
const _balance = Store.from<Address, U256>('balance');
const _freeze = Store.from<Address, U256>('freeze');
export function init(tokenName: string, symbol: string, totalSupply: U256, decimals: u64, owner: Address): void {
// tokenName || symbol || totalSupply || decimals || owner
Globals.set<string>('tokenName', tokenName);
Globals.set<string>('symbol', symbol);
Globals.set<U256>('totalSupply', totalSupply);
Globals.set<u64>('decimals', decimals);
Globals.set<Address>('owner', owner);
_balance.set(owner, totalSupply);
}
// display balance
export function balanceOf(addr: Address): U256 {
return _balance.getOrDefault(addr, U256.ZERO);
}
/* Send coins */
export function transfer(to: Address, amount: U256): void {
const msg = Context.msg();
assert(amount > U256.ZERO, 'amount is not positive');
let b = balanceOf(msg.sender)
assert(b >= amount, 'balance is not enough');
_balance.set(to, balanceOf(to) + amount);
_balance.set(msg.sender, balanceOf(msg.sender) - amount);
}
构造合约部署事务
const contract = new tdsSDK.Contract()
// 编译合约得到字节码
contract.binary = await tdsSDK.compileContract(ascPath, 'assembly/coin.ts')
// 得到 abi
contract.abi = tdsSDK.compileABI(fs.readFileSync('assembly/coin.ts'))
// 写入 abi 文件
fs.writeFilesSync('coin.abi.json', JSON.stringify(contract.abi))
// 获取 nonce
builder.nonce = (await rpc.getNonce(addr)) + 1
// 传入合约构造器参数
let tx = builder.buildDeploy(contract, {
tokenName: 'doge',
symbol: 'DOGE',
totalSupply: '90000000000000000',
decimals: 8,
owner: addr
}, 0)
构造合约调用事务
const abi = require('./coin.abi.json') // abi 文件
const contract = new tdsSDK.Contract('****address****', abi)
const tx = builder.buildContractCall(contract, 'transfer', ['****address****', 100000000], 0)
查看合约
const abi = require('./coin.abi.json') // abi 文件
const contract = new tdsSDK.Contract('****address****', abi)
rpc.viewContract(contract, 'balanceOf', ['****address****'])
.then(console.log)
生成 keystore
const password = 'abc123'
const ks = tdsSDK.createKeyStore(password)
console.log(ks)
读取 keystore 中私钥
const sk = tdsSDK.readKeyStore(
{"publicKey":"0230632aa4863e9c0c027de7542b434adae169a8c439f595b244696bce306c8191","crypto":{"cipher":"sm4-128-ecb","cipherText":"f347b48dd1931d66d2e5bb8f4d030b3c5c5db9f32c3c763e6fadcd77de1b6886","iv":"5811eafed7a69b7f84c6b62d473afb0e","salt":"8d5196266292ff95778290983139ec427edea8639d0db37b9298924bf42879e6"},"id":"504e5c56-32da-41f8-8096-5160eda5936c","version":"1","mac":"a57423d830fd5267402838d7dc4e2ec6c54f8120797c369bc412b08585c32c88","kdf":"sm2-kdf","address":"521e3435917a9fe7b3e2841d8f9cf943758bf3e1"},
"123456"
)
创建poa认证服务并启动
// ['03e3198bd3c12ab68566fcf14903dee3456cd1e1d8a0121ca04aade9b752750216'] 是公钥白名单,只有持有此公钥对应的私钥的节点才能访问这个服务
const server = tdsSDK.createAuthServer(sk, ['03e3198bd3c12ab68566fcf14903dee3456cd1e1d8a0121ca04aade9b752750216'])
server.listen(3000, function () {
console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来进行访问')
})
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago