编码
leb128 编码
LEB128(Little-Endian Base 128)是一种基于小端法表示的128位、可变长度的编码格式。它既可以表示无符号整数(uleb128,unsigned LEB128),也可以表示有符号的整数(sleb128,signed LEB128)
RFC 7049 编码
简明二进制对象展现(CBOR,Concise Binary Object Representation)是一种提供良好压缩性,扩展性强,不需要进行版本协商的二进制数据交换形式。这些特性使它有别于早期的ASN.1和MessagePack等二进制方式。RFC 7049定义了详细的CBOR格式与说明。
算法
blake2
BLAKE2的定位是目前安全系数最高的哈希函数。BLAKE2是基于BLAKE实现的,BLAKE是2008年被提交至SHA-3竞赛的一种哈希函数。
BLAKE2不仅仅只是一个简单的哈希函数而已!首先,BLAKE2有两大主要版本:BLAKE2b和BLAKE2s。BLAKE2b是BLAKE的64位版本,它可以生成最高512位的任意长度哈希。BLAKE2s是BLAKE的32位版本,它可以生成最高256位的任意长度哈希。
BLAKE2x是对BLAKE2的简单扩展,它可以生成任意长度的哈希值(长度不受限制)。
Node.js 实现
引用包
npm install --save base32-decode
npm install leb128
npm install blake2
npm install --save cbor
引用文件
blake2 = require('blake2')
leb128 = require('leb128')
base32Decode = require('base32-decode')
cbor = require('cbor');
//buff Array 转换
function toBuffer(ab) {
var buf = new Buffer(ab.byteLength);
var view = new Uint8Array(ab);
for (var i = 0; i < buf.length; ++i) {
buf[i] = view[i];
}
return buf;
}
//get address
function getAddressBuff(address) {
address1 = address.substring(2, address.length).toUpperCase()
addressBuff = base32Decode(address1, 'RFC4648')
addressStr = toBuffer(addressBuff).toString('hex')
addressStr = "01" + addressStr.substring(0, addressStr.length - 8)
return new Buffer(addressStr, 'hex')
}
//get blake2b
function getBlake2b(buff, len) {
h1 = blake2.createHash('blake2b', {digestLength: len});
h1.update(buff);
return h1.digest();
}
//get Sign
function getSign(msgBuff, priKey) {
msgHash = getBlake2b(msgBuff, 32);
sig = util.ecsign(msgHash, priKey);
sign = sig.r.toString('hex') + sig.s.toString('hex') + '00'
return new Buffer(sign, 'hex').toString('base64')
}
//get leb
function getLebBuff(fil) {
return leb128.signed.encode((fil * autofil).toString())
}
//send message
function signedMsg(jsString, privatekey) {
object = JSON.parse(jsString)
addrFromBuff = getAddressBuff(object.from)
addrToBuff = getAddressBuff(object.to)
nonce = leb128.unsigned.encode(object.nonce)
value = getLebBuff(object.value)
method = object.method
params = object.params
gasLimit = leb128.unsigned.encode(object.gasLimit)
gasPrice = getLebBuff(object.gasPrice)
json = {
"to": addrToBuff,
"from": addrFromBuff,
"nonce": nonce,
"value": value,
"method": method,
"params": params,
"gasLimit":gasLimit,
"gasPrice":gasPrice
}
msg = cbor.encode(json);
prikey = new Buffer(privatekey, 'hex')
signature = getSign(msg, prikey)
signedJson = {
"meteredMessage": {
"message": {
"to": object.to,
"from": object.from,
"nonce": object.nonce,
"value": object.value,
"method": object.method,
"params": null
},
"gasPrice": object.gasPrice,
"gasLimit": object.gasLimit
},
"signature": signature
}
return JSON.stringify(signedJson)
}
input
json = {
"to": "t16vql5i7qimlfhu7dme4sdjph4voeftcbmmowz5q",
"from": "t1aguquffejbws7ebwntugc65tpkgojen3ku2x2vq",
"nonce": "0",
"value": "123",
"method": "",
"params": null,
"gasPrice": "0.001",
"gasLimit": "100"
}
jsString = JSON.stringify(json)
privatekey = privateKey0.toString('hex')
'b770b200ec122d38a72b2eb62b2ea1f85021b7dff556b14707aba0d7ee80b21a'
signedMsg(jsString, privatekey)