使用流程
生成地址
z-addr 地址. 即匿名地址, 该地址通过一个 sk
和 一个 d
唯一确定.
可以公布你的 z-addr
让别人转账给你, 其他的各种 key 都用来做某种操作. d
参数往往用来形成 HD 钱包, 可以认为是地址序列.
具体如下.
// sk: spending key => ask, nsk, ovk
// ask: spend authorizing key, 256 => ak
// nsk: proof authorizing key, 256 => nk
// ovk: outgoing viewing key, 256
// ivk: incoming viewing key, 256 => pkD
// d: diversifier, 11bytes
// pkD: the public key of the address, g_d^ivk
// pkD + d => z-addr
例如: ztron1m445gx74mjuuyhkyru5hrx886jszfga4a7dk3mg4uarrl0cru649jz4928tm6rqul2pg645hqv5
该地址格式为 bech32 格式, ztron1
为固定前缀. 后为编码的 pkD
和 d
信息.
地址和 key
相关 API 如下:
wallet/getspendingkey
> generating sk
wallet/getexpandedspendingkey
> sk => aks, nsk, ovk
wallet/getakfromask
> ask => ak
wallet/getnkfromnsk
> nsk => nk
wallet/getincomingviewingkey
> ak, nk => ivk
wallet/getdiversifier
> generating d
wallet/getzenpaymentaddress
> ivk, d => z-addr, pkD
为了方便一次性生成地址, TRONZ 提供了 wallet/getnewshieldedaddress
API, 支持一次性生成所有 Key 和地址.
> curl https://api.nileex.io/wallet/getnewshieldedaddress
{
"sk": "03a7e......ommitted......71704fec2d3d",
"ask": "c6ca0277c790......ommitted......1bd47713dc5074e0b",
"nsk": "afc20d0......ommitted......4ae18ad62306",
"ovk": "d893......ommitted......75476d6d84",
"ak": "c682ba......ommitted......a2b411e7d134",
"nk": "458d......ommitted......ea8b5408a4",
"ivk": "847e......ommitted......5f40b6bb76400",
"d": "82a05......ommitted......69f6812",
"pkD": "7cd04d......ommitted......dd242f5bbdccdfce01",
"payment_address": "ztron1s2s9fpf2v2l3d8......ommitted......4h0wvml8qzjzrv36"
}
匿名 TRC20 合约
合约地址 ShieldedTRC20.sol.
一个匿名 TRC20 合约, 必须绑定到一个已有的 TRC20 合约上. 如下是关键函数列表:
constructor (address trc20ContractAddress, uint256 scalingFactorExp)
function burn(bytes32[10] input, bytes32[2] spendAuthoritySignature, uint256 rawValue, bytes32[2] bindingSignature, address payTo, bytes32[3] c)
=> burn(bytes32[10],bytes32[2],uint256,bytes32[2],address,bytes32[3]) [4d013fde]
function mint(uint256 rawValue, bytes32[9] output, bytes32[2] bindingSignature, bytes32[21] c)
=> mint(uint256,bytes32[9],bytes32[2],bytes32[21]) [855d175e]
function transfer(bytes32[10][] input, bytes32[2][] spendAuthoritySignature, bytes32[9][] output, bytes32[2] bindingSignature, bytes32[21][] c)
=> transfer(bytes32[10][],bytes32[2][],bytes32[9][],bytes32[2],bytes32[21][]) [9110a55b]
function scalingFactor() view returns (uint256)
=> scalingFactor() [ed3437f8]
function getPath(uint256 position) view returns (bytes32, bytes32[32])
=> getPath(uint256) [e1765073]
基于 TRON 对该套 API 的封装, 实际使用不需要关注 burn
, mint
, transfer
函数的参数, 只需通过函数签名和工具 API 返回的字节串调用合约即可.
使用流程
第一步, 部署合约, 调用合约构造函数完成初始化
这里在 Nile Testnet 映射 JST token TF17BgPaZYbz8oxbjhriubPDsA7ArKoLX3
到匿名 TRC20 合约.
对应的匿名 TRC20 合约地址是 TEkQTDyZmbY6hngxdAsxzxy9r3bUNhRjdS
. 构造函数参数为
(TF17BgPaZYbz8oxbjhriubPDsA7ArKoLX3, 18)
. 所以 scalingFactor
是 10 ** 18, 即 JST 的小数点位.
Solidity 编译器需要使用 https://github.com/tronprotocol/solidity 的 develop
分支.
然后我们的初始地址 TJRabPrwbZy45sbavfcjinPJC18kjpRTv8
内通过 Nile Testnet 水龙头 地址获得测试用 JST token 代币.
给 z 地址转账 - 铸币 mint
转账前有一个重要操作, 使用 TRC20 的 approve
转账方式, 给匿名合约地址授权.
=> transferFrom(from: addr, to: addr, uint265)
授权 1000000 单位 TRC20 代币, 这样匿名 TRC20 合约就有权限使用 transferFrom
方式转账.
假设我们的目标地址是 ztron1s2s9fpf2v2l3d8mgzf7dqnfptkrlmyekvaqlw50lpf8dz8xkdgphjuxaysh4h0wvml8qzjzrv36
.
先创建 rcm
:
> curl https://api.nileex.io/wallet/getrcm
{"value": "720c84c8b41b3dcfcc1d5997e196e6de99f07aefb9274e285a23c5599ea2c40a"}
随后调用合约参数构造 API wallet/createshieldedcontractparameters
:
{
'from_amount': '10000',
'shielded_receives': {'note': {
'value': 1000,
'payment_address': 'ztron1s2s9fpf2v2l3d8mgzf7dqnfptkrlmyekvaqlw50lpf8dz8xkdgphjuxaysh4h0wvml8qzjzrv36',
'rcm': '720c84c8b41b3dcfcc1d5997e196e6de99f07aefb9274e285a23c5599ea2c40a',
'memo': 'HEX'}},
'shielded_TRC20_contract_address': '4148c0020ff778c4090bf196e39d51b92bf5a647b1'
}
- 其中
from_amount
只能是字符串型 note
内value
是from_amount
除以scalingFactor
得到若干参数, 其中最重要的是 trigger_contract_input
{'binding_signature': '......',
'message_hash': '.....',
'parameter_type': 'mint',
'receive_description': [{'c_enc': '..........',
'c_out': '.....',
'epk': '...',
'note_commitment': '.....',
'value_commitment': '.....',
'zkproof': '.....'}],
'trigger_contract_input': '.....'
}
[855d175e]
(mint 函数的签名) 拼接 trigger_contract_input, 得到调用合约 mint
函数的最终参数, 使用发送地址调用合约并签名广播即可.
查询转入转账
使用 wallet/scanshieldedtrc20notesbyivk
API.
提供 z-addr 的 ivk, ak, nk 返回 Note 列表. 一次只能扫描 1000 个区块.
返回的 Note 会附带 is_spent
信息.
z 地址之间相互转账 - transfer
转账基于 Note 到 Note, 可以是 1-2 个 note 转入 1-2 个 note, 金额必须平衡, 使用找零机制。
需要注意的是 alpha
, rcm
均为随机数。需要通过 wallet/getrcm
获取.
例子 txid: f0274768b212cf1729a137926980315be04ff46d265416183d85a97bccc68b8b
查询转出转账
使用 wallet/scanshieldedtrc20notesbyovk
API
提供 z-addr 的 ovk. 查询转出的 note 列表.
返回的 Note 不带 is_spent
字段, 但 is_spent
= True.
查询 Note 是否被花掉
使用 wallet/isshieldedtrc20contractNoteSpent
API. 提供 ak
, nk
.
z 地址转入到透明地址 - burn
操作及 key 参数同 transfer.
参考文档
Updated 7 months ago