StarkNet 是一种无需许可的去中心化 Validity-Rollup(也称为“ZK-Rollup”)零知识证明系统。它作为以太坊上的 L2 网络运行,使任何 dApp 都能实现无限的计算规模——而不会损害以太坊的可组合性和安全性,这要归功于 StarkNet 对最安全和最具可扩展性的加密证明系统——STARK 的依赖。
Cairo是一种用于编写可证明程序的编程语言,其中一方可以向另一方证明某个计算已正确执行。Cairo和类似的证明系统可用于为区块链提供可扩展性。
starknet.js是starknet上类似于ether.js的开发库,由于目前starknet处于早期,而且starknet.js文档也跟不上库更新的速度,因此在使用最新库的时候就会出现一定的问题。比如,当cairo函数参数为Uint256时,按照官方文档的方式传参会出现参数数量的问题。
使用下面这种参数传递方式是没有问题的,但是starknet有一个特色就是可以在一笔交易中同时与多个合约进行交互(multiCall),采用这样的方式无法使用starknet的这个功能
使用这种方式传参是会出现问题的
发送交易之后可以看到出现下面的情况。这是因为采用这样的方式传参,会把参数数组的长度一并打包提交,实际提交的数据是
[
1
,
100
]
[1,100]
[1,100],在cairo语言中,Uint256是有由两个felt构成的,结构为[felt, felt],第一个元素为低位,第二个元素为高位,所以实际提交的数据会很大。
解决办法有两种,各有优缺点。
- 第一种是直接用数组传递参数,比如说在Erc20 token的授权函数中,使用如下的方式传递参数
signer.execute({
contractAddress: contractAddress,
entrypoint: "approve",
calldata: [spenderAddress, spendValue, '0']
});
采用这种方式传递参数是直接将Uint256拆分为低位和高位两个元素进行传递,简单直观,坏处是不容易看出具体传递的实参对应哪个形参。
- 第二种方式是使用compileCalldata,将Uint256当做结构体来处理,代码如下
signer.execute(
{
contractAddress: contractAddress,
entrypoint: "approve",
calldata: stark.compileCalldata({
spender: spenderAddress,
amount: {type: 'struct', low: spendValue, high: '0'},
})
}
);
采用这种方式的好处就是能够清晰的看到参数对应关系,坏处是增加了代码量。
当然,由于现在starknet.js也处于开发的早期,相信经过一段时间的发展,starknet.js会像ethers.js一样好用。