npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

keystore_wdc

v0.4.33-beta

Published

``` npm i keystore_wdc; const KeyStore = require('keystore_wdc'); const ks = new KeyStore(); ``` #### 生成keystore ``` async function create(){ const keystore = await ks.Create("your password"); } ``` * 返回keystore,密码格式不正确返回-1。

Downloads

78

Readme

js-sdk

一、本地方法

sdk所有方法异常返回5000
npm i keystore_wdc;
const KeyStore = require('keystore_wdc');
const ks = new KeyStore();

生成keystore

async function create(){
     const keystore = await ks.Create("your password");
}
  • 返回keystore,密码格式不正确返回-1。

修改keystore密码

async function modifypassword(){
     const keystore = await ks.modifyPassword("your keystore","your password","your newpassword");
}
  • 返回keystore,密码格式不正确返回-1。

校验地址合法性

const lawful = ks.verifyAddress("your address");

返回值:

  • 0 合法
  • -1 地址格式不正确
  • -2 错误地址

地址转公钥哈希

const pubkeyHash = ks.addressToPubkeyHash("your address")
  • 返回公钥哈希

公钥哈希转地址

const address = ks.pubkeyHashToaddress("your pubkeyHash",type)
type:  '1' WX前缀的普通地址
       '2' WR前缀的合约地址
  • 返回地址

私钥转公钥

 const pubkey = ks.prikeyToPubkey("your prikey");
  • 返回公钥

通过keystore获取公钥

 async function getpubkey(){
 	const pubkey = await ks.keystoreToPubkey("your keystore","your password");
 }
  • 返回公钥

通过keystore获取私钥

 async function getprikey(){
 	const prikey = await ks.DecryptSecretKeyfull("your keystore","your password");
 }
  • 返回私钥

构造转账实务

const transfer = ks.ClientToTransferAccount(fromPubkey,toPubkeyHash,amount,prikeyStr,nonce);

fromPubkey:发起转转账者公钥
toPubkeyHash:接收者公钥哈希
amount:转账金额(必须是字符串!)
prikey:私钥
nonce:nonce(通过节点获取)
  • 返回:
  • 'txHash':事务哈希
  • 'transaction': 整个事务

更新keystore版本

 async function updateKeystoreVersion1to2(){
 	const keystore = await ks.updateKeystoreVersion1to2("your keystore","your password");
 }
  • 返回keystore

浏览器环境使用

const argon2b = require('keystore_wdc/argon2b')
ks.setArgon2(argon2b)

二、节点RPC接口

连接节点,ip+端口+调用方法+参数

Content-Type: application/json;charset=UTF-8

返回格式

{"message":"","data":[],"statusCode":int}
  • message:描述
  • data :数据
  • statusCode:
{
    2000 正确
    2100 已确认
    2200 未确认
    5000 错误
    6000 格式错误
    7000 校验错误
    8000 异常
}

1.0 获取Nonce

   方法:sendNonce(POST)     
	参数:pubkeyhash(String)  
	返回:
	{"message":"","data":[],"statusCode":int}
	data:Nonce(Long)

1.1 获取余额

   方法:sendBalance(POST)   
	参数:pubkeyhash(十六进制字符串) 	
 	返回:
 	{"message":"","data":[],"statusCode":int}
	data:balance(Long)

1.2 广播事务

   方法: sendTransaction(POST)	
	参数:traninfo(String)
	返回:
 	{"message":"","data":[],"statusCode":int}

1.3 查询当前区块高度

   方法:height(GET)
    返回:
	{"message":"","data":0,"statusCode":int}
	data:height(Long)

1.4 根据事务哈希获得所在区块哈希以及高度

   方法:blockHash(GET)
	参数:txHash(String)
	返回:
	{
    	data :定义如下;
        statusCode(int):int
	    message(String):""
    }
    data:
   {
        "blockHash":区块哈希(十六进制字符串), 
        "height":区块高度(Long)
   }

1.5 根据事务哈希获得区块确认状态(GET)

   方法:transactionConfirmed
	参数:txHash(String)
	返回: 
   {"message":"","data":[],"statusCode":int}
   statusCode: status(int)

1.6 根据区块高度获取事务列表

   方法: getTransactionHeight(POST) 
   参数: int height 区块高度
   返回格式:{"message":"SUCCESS","data":[],"statusCode":1}
   data格式:
	String block_hash; 区块哈希16进制字符串
	long height; 区块高度
	int version; 版本号
	String tx_hash; 事务哈希16进制字符串
	int type;  事务类型
	long nonce;nonce
	String from;  发起者公钥16进制字符串
	long gas_price; 事务手续费单价
	long amount; 金额
	String payload; payload数据
	String signature; 签名16进制字符串
	String to;  接受者公钥哈希16进制字符串

1.7 通过区块哈希获取事务列表

   方法:getTransactionBlcok(POST)
   参数 String blockhash 区块哈希16进制字符串
   返回格式:{"message":"SUCCESS","data":[],"statusCode":1}
   data格式:
	String block_hash; 区块哈希16进制字符串
	long height; 区块高度
	int version; 版本号
	String tx_hash; 事务哈希16进制字符串
	int type;  事务类型
	long nonce;nonce
	String from;  发起者公钥16进制字符串
	long gas_price; 事务手续费单价
	long amount; 金额
	String payload; payload数据
	String signature; 签名16进制字符串
	String to;  接受者公钥哈希16进制字符串

1.8 通过事务哈希获取事务

    方法:transaction\(事务哈希) (GET)
    返回:{"message":"SUCCESS","data":[],"statusCode":1}
    data格式:
    {
      "transactionHash": "e75d61e1b872f67cccc37c4a5b354d21dd90a20f04a41a8536b9b6a1b30ccf41", // 事务哈希
      "version": 1, // 事务版本 默认为 0
      "type": 0,  // 事务类型 0 是 coinbase 1 是 转账
      "nonce": 5916, // nonce 值,用于防止重放攻击
      "from": "0000000000000000000000000000000000000000000000000000000000000000", // 发送者的公钥, 用于验证签名
      "gasPrice": 0, // gasPrice 用于计算手续费
      "amount": 2000000000, // 交易数量,单位是 brain
      "payload": null, // payload 用于数据存证,一般填null
      "to": "08f74cb61f41f692011a5e66e3c038969eb0ec75", // 接收者的地址
      "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // 签名
      "blockHash": "e2ccac56f58adb3f2f77edd96645931fac93dd058e7da21421d95f2ac9cc44ac", // 事务所在区块的哈希
      "fee": 0,  // 手续费
      "blockHeight": 13026 // 事务所在区块高度
}

1.9 获取节点版本信息

Function:version
GET/HTTP/1.1/Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Request URL: http://00.000.0.000:19585/version
Parameter:
Demo:
    GET http://00.000.0.000:19585/version
Response Body:
    {"message":"","data":[],"statusCode":int}
    data:版本信息

智能合约

编译、部署智能合约

  1. 编译智能合约需要node环境,并且确保安装了正确版本的 asc,如果没有安装,在你的项目的根目录的 pacakge.json 的 devDependencies 添加 "assemblyscript": "^0.14.10" ,并且执行 npm install,node 环境使用 tool.RPC 需要安装 websocket,npm install ws --save-dev

  2. 在你的项目根目录下新建一个文件命名为 coin.ts

/**
 * erc 20 example in assembly script
 */
 
import { Util, U256, Globals, ABI_DATA_TYPE, ___idof } from './node_modules/keystore_wdc/lib'
import { Store } from './node_modules/keystore_wdc/lib'
import { Context, Address } from './node_modules/keystore_wdc/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): Address {
    // 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);
    return Context.self();
}
 
// display balance
export function balanceOf(addr: Address): U256 {
    return _balance.getOrDefault(addr, U256.ZERO);
}
 
export function freezeOf(addr: Address): U256 {
    return _freeze.getOrDefault(addr, U256.ZERO);
}
 
export function tokenName(): string {
    return Globals.get<string>('tokenName');
}
 
export function symbol(): string {
    return Globals.get<string>('symbol');
}
 
export function decimals(): u64 {
    return Globals.get<u64>('decimals');
}
 
export function totalSupply(): U256 {
    return Globals.get<U256>('totalSupply');
}
 
export function owner(): Address {
    return Globals.get<Address>('owner');
}
 
/* 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);
    Context.emit<Transfer>(new Transfer(msg.sender, to, amount));
}
 
// 冻结
export function freeze(amount: U256): void {
    const msg = Context.msg();
    assert(balanceOf(msg.sender) >= amount, 'balance is not enough');
    _balance.set(msg.sender, balanceOf(msg.sender) - amount);
    _freeze.set(msg.sender, freezeOf(msg.sender) + amount);
    Context.emit<Freeze>(new Freeze(msg.sender, amount));
}
 
// 解冻
export function unfreeze(amount: U256): void {
    const msg = Context.msg();
    assert(freezeOf(msg.sender) >= amount, 'freeze is not enough');
    _freeze.set(msg.sender, freezeOf(msg.sender) - amount);
    _balance.set(msg.sender, balanceOf(msg.sender) + amount);
    Context.emit<Unfreeze>(new Unfreeze(msg.sender, amount));
}
 
/* Allow another contract to spend some tokens in your behalf */
export function approve(to: Address, amount: U256): void {
    const msg = Context.msg();
    assert(amount > U256.ZERO, 'amount is not positive');
    _setAllowanceOf(msg.sender, to, amount);
    Context.emit<Approve>(new Approve(msg.sender, to, amount));
}
 
export function allowanceOf(from: Address, sender: Address): U256 {
    const db = getAllowanceDB(from);
    return db.getOrDefault(sender, U256.ZERO);
}
 
/* A contract attempts to get the coins */
export function transferFrom(from: Address, to: Address, amount: U256): void {
    const msg = Context.msg();
    assert(amount > U256.ZERO, 'amount is not positive');
    const allowance = allowanceOf(from, msg.sender);
    const balance = balanceOf(from);
    assert(balance >= amount, 'balance is not enough');
    assert(allowance >= amount, 'allowance is not enough');
    _setAllowanceOf(from, msg.sender, allowanceOf(from, msg.sender) - amount);
    _balance.set(from, balanceOf(from) - amount);
    _balance.set(to, balanceOf(to) + amount);
    Context.emit<Transfer>(new Transfer(from, to, amount));
}
 
// 许可金
function getAllowanceDB(addr: Address): Store<Address, U256> {
    const prefix = Util.concatBytes(Util.str2bin('allowance'), addr.buf);
    return new Store<Address, U256>(prefix);
}
 
 
function _setAllowanceOf(from: Address, msgSender: Address, amount: U256): void {
    const db = getAllowanceDB(from);
    db.set(msgSender, amount);
}
 
// 所有合约的主文件必须声明此函数
export function __idof(type: ABI_DATA_TYPE): u32 {
    return ___idof(type);
}
 
@unmanaged
class Approve {
    constructor(
        readonly from: Address,
        readonly sender: Address,
        readonly amount: U256) {
    }
}
 
@unmanaged class Transfer {
    constructor(readonly from: Address, readonly to: Address, readonly value: U256) { }
}
 
@unmanaged class Freeze {
    constructor(readonly from: Address, readonly value: U256) { }
}
 
@unmanaged class Unfreeze {
    constructor(readonly from: Address, readonly value: U256) { }
}
  1. 在你的项目根目录下新建一个 deploy.js文件,编写部署脚本
const sk = '****'
const addr = '****'
const tool = require('keystore_wdc/contract') // 
const fs = require('fs')

// 用于构造合约事务
const builder = new tool.TransactionBuilder(/* 事务默认版本号 */1, sk, /*gas限制,填写0不限制gas*/0, /*gas单价*/ 200000)
// 这里是 asc 的路径,
const ascPath = 'node_modules/.bin/asc';
 
// 用于调用节点 rpc
const rpc = new tool.RPC('localhost', 19585)
 
async function deploy(){
   const contract = new tool.Contract()
   // 编译合约得到字节码
   contract.binary = await tool.compileContract(ascPath, 'coin.ts')
   // 编译得到 abi
   contract.abi = tool.compileABI(fs.readFileSync('coin.ts'))
   // 写入 abi,便于以后使用
   fs.writeFileSync('coin.abi.json', JSON.stringify(contract.abi))
 
   // 获取 nonce,填入 builder,这样 builder 生成的事务都是签名过的事务
   builder.nonce = (await rpc.getNonce(addr)) + 1
   // 生成合约部署的事务
   let tx = builder.buildDeploy(contract, {
      tokenName: 'doge',
      symbol: 'DOGE',
      totalSupply: '90000000000000000',
      decimals: 8,
      owner: addr
   }, 0)
   // 也可以用 tx.sign(sk) 手动进行签名
 
   // 部署的合约地址可以根据事务哈希值计算得到
   console.log(tool.getContractAddress(tx.getHash()))
 
   // 发送事务并等待事务打包进入区块
   console.dir(await rpc.sendAndObserve(tx, tool.TX_STATUS.INCLUDED), {depth: null})
   // 也可以直接发送,不等待事务打包 rpc.sendTransaction(tx)
}

deploy().catch(console.error)
  1. 合约部署后,可以查看合约中的方法
const contractAddr = '****' // 这里填合约部署后生成的地址
const abi = require('./coin.abi.json') // 部署合约时生成的 abi 
const tool = require('keystore_wdc/contract')

// 用于构造合约事务

// 用于调用节点 rpc
const rpc = new tool.RPC('localhost', 19585)

async function viewBalance(){
   const contract = new tool.Contract(contractAddr, abi)
   console.log(await rpc.viewContract(contract, 'balanceOf', ['14zBnDtf8SqHjzVGYUupBtwnWWXx8Uqg3u']))
}
  1. 合约部署后,也可以调用合约中的方法构造事务
const contractAddr = '****' // 这里填合约部署后生成的地址
const abi = require('./coin.abi.json') // 部署合约时生成的 abi 
const tool = require('keystore_wdc/contract')
const sk = '****' // 填写你的私钥
const yourAddress = '****' // 填写你的地址

// 用于构造合约事务
const builder = new tool.TransactionBuilder(/* 事务默认版本号 */1, sk, /*gas限制,填写0不限制gas*/0, /*gas单价*/ 200000)

// 用于调用节点 rpc
const rpc = new tool.RPC('localhost', 19585)

async function transfer(){
   const contract = new tool.Contract(contractAddr, abi)
   contract.address = contractAddr
   // 构造合约转账事务,给自己转账
   let tx = builder.buildContractCall(contract, 'transfer', [yourAddress, 100000000])
   // 设置 nonce
   tx.nonce = (await rpc.getNonce(yourAddress)) + 1 // 这里的 nonce 可以从节点获取 
   tx.sign(sk)
   console.dir(await rpc.sendAndObserve(tx, tool.TX_STATUS.INCLUDED), {depth: null})
}