Skip to content

PrivacyTransaction

Fnatic.wang edited this page Oct 18, 2019 · 4 revisions

匿名隐私交易

隐私交易是指用户向另一个地址转账,但是不直接指定谁是接收者的一种交易方式。使用隐私交易,其他人可以看到用户进行了一个交易事务,但是不能知道收件人是谁。隐私交易在usechain上通过协议内置预编译的智能合约实现。智能合约地址和abi为硬编码,并对外公开用于用户使用。usechain上的隐私交易需要两个步骤,首先发送方将ETH锁定在内置合约中,然后接受方从契约中赎回。 隐私交易图例

当用户在隐私交易合约中锁定ETH时,不会看到预期的接受者是谁。这是因为锁事务在事务调用数据中不包含收件人的地址,而只包含来自收件人一次性地址。并且在接受者赎回锁定的ETH的交易中使用了环签名。因此,虽然我们可以看到将资金锁定在隐私交易合约中的交易,以及从隐私交易合约中赎回资金的交易,但是我们也不能将锁定和赎回交易联系起来,从而达到了隐私交易的目的。

匿名隐私交易的支持的面额为10 20 50 100 200 500 1000 5000 50000(ETH),暂不支持其他面额。需要注意的是:如果接受者帐户为他人所有,你应该请求接受者向你提供一次性地址,而不是自己从接受者的地址生成一次性地址。当然,如果你为接受者生成了一次性地址,则需要在锁定ETH后,将生成的一次性地址告知给接受者,以便其可以通过这个一次性地址赎回被你锁定的ETH。

隐私交易合约地址

0x0000000000000000000000000000000000000064

隐私交易合约ABI

[{"constant":false,"type":"function","stateMutability":"nonpayable","inputs":[{"name":"OtaAddr","type":"string"},{"name":"Value","type":"uint256"}],"name":"buyCoinNote","outputs":[{"name":"OtaAddr","type":"string"},{"name":"Value","type":"uint256"}]},{"constant":false,"type":"function","inputs":[{"name":"RingSignedData","type":"string"},{"name":"Value","type":"uint256"}],"name":"refundCoin","outputs":[{"name":"RingSignedData","type":"string"},{"name":"Value","type":"uint256"}]},{"constant":false,"inputs":[],"name":"getCoins","outputs":[{"name":"Value","type":"uint256"}]}]

下文为隐私交易的详细步骤,预设交易场景为:account1往account2账户执行10ETH的匿名隐私转账交易。

发送方锁定资金

  • 解锁账户
> personal.unlockAccount(eth.account[1],"passwd",0);
> personal.unlockAccount(eth.account[2],"passwd",0);
  • 添加隐私交易合约abi和地址,合约地址0x0000000000000000000000000000000000000064为预编译合约地址,其内部实现了匿名隐私交易。
> abiDef = [{"constant":false,"type":"function","stateMutability":"nonpayable","inputs":[{"name":"OtaAddr","type":"string"},{"name":"Value","type":"uint256"}],"name":"buyCoinNote","outputs":[{"name":"OtaAddr","type":"string"},{"name":"Value","type":"uint256"}]},{"constant":false,"type":"function","inputs":[{"name":"RingSignedData","type":"string"},{"name":"Value","type":"uint256"}],"name":"refundCoin","outputs":[{"name":"RingSignedData","type":"string"},{"name":"Value","type":"uint256"}]},{"constant":false,"inputs":[],"name":"getCoins","outputs":[{"name":"Value","type":"uint256"}]}];
> contractDef = eth.contract(abiDef);
> coinContractAddr = "0x0000000000000000000000000000000000000064";
> coinContract = contractDef.at(coinContractAddr);

保证account1和account2账户有一定数量的ETH。

> eth.getBalance(eth.accounts[1])
> eth.getBalance(eth.accounts[2])
  • 为account1生成一次性地址。
> var useAddr = eth.getUseAddress(eth.accounts[2]);
> var otaAddr = eth.generateOneTimeAddress(useAddr);
  • 初始化调用隐私交易合约的data
> txBuyData = coinContract.buyCoinNote.getData(otaAddr, 10000000000000000000);
  • account1发送交易到隐私交易合约地址,合约执行时将ETH进行锁定。
> eth.sendTransaction({from:eth.accounts[1], to:coinContractAddr, value:10000000000000000000, data:txBuyData, gas: 1000000});
  • 查看account1的余额,转账金额已经被扣除锁定到了合约内。
> eth.getBalance(eth.accounts[1])

接收方赎回资金

接下来的步骤为account2赎回account1锁定的ETH。

  • 获取多个一次性地址用于环签名所需要的数据。
> var mixUseAddresses = eth.getOTAMixSet(otaAddr,2);
注:如整个链第一次进行该金额的匿名交易,因为没有更多的该金额的一次性地址,会报以下错误:

Error: too more required ota number! balance:10000000000000000000, exist count:1

则需要按照上文描述,再生成2个一次性地址锁定10ETH进行后续的匿名交易。之后再次进行该金额的匿名交易,就有进行环签名所需的数据了。当然后面生成的这两个一次性地址锁定的ETH,也可以赎回。
> var mixSetWith0x = []
 for (i = 0; i < mixUseAddresses.length; i++){
	 mixSetWith0x.push(mixUseAddresses[i])
 }
  • account2获取一次性地址的私钥用于环签名
> keyPairs = eth.computeOTAPPKeys(eth.accounts[2], otaAddr).split('+');
> privateKey = keyPairs[0];
  • 生成环签名签名数据
> var ringSignData = eth.genRingSignData(eth.accounts[2], privateKey, mixSetWith0x.join("+"))
  • 构造赎回交易的data
> var txRefundData = coinContract.refundCoin.getData(ringSignData, 10000000000000000000)
  • 发送赎回交易到隐私交易合约地址
> eth.sendTransaction({from:eth.accounts[2], to:coinContractAddr, value:0, data:txRefundData, gas: 2000000});
  • 查询account1和account2的余额,验证交易是否正确
> eth.getBalance(eth.accounts[1])
> eth.getBalance(eth.accounts[2])
Clone this wiki locally