Compare commits
24 Commits
proposal_a
...
v2
Author | SHA1 | Date | |
---|---|---|---|
5db3741ea9 | |||
427ebea84b | |||
|
2a26a90940 | ||
|
9d0262189e | ||
|
b3277137ba | ||
|
d93d7c8870 | ||
|
9f095bfcb2 | ||
|
6d219e19ee | ||
|
18518856ff | ||
|
ca446c79cd | ||
|
3ae6087f65 | ||
|
87babe41d3 | ||
|
e42a2afb43 | ||
|
adf675edd9 | ||
|
15eaac2f2e | ||
|
cd2ea92084 | ||
|
6850d6a6c4 | ||
|
97b486b9ba | ||
|
f02347500b | ||
|
a326f3e14f | ||
|
b9570ea3c3 | ||
|
44e9d7d645 | ||
|
5a82105f24 | ||
|
01ca620e7c |
1
.npmrc
Normal file
1
.npmrc
Normal file
@ -0,0 +1 @@
|
||||
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/
|
@ -2,11 +2,11 @@
|
||||
|
||||
## v2 changes
|
||||
|
||||
`TornadoTrees.sol` is no longer part of this project. It migrated to [tornado-trees](https://github.com/tornadocash/tornado-trees)
|
||||
`TornadoTrees.sol` is no longer part of this project. It migrated to [@tornado/trees](https://git.tornado.ws/tornado-packages/tornado-trees)
|
||||
|
||||
## Dependencies
|
||||
|
||||
1. node 12
|
||||
1. node 16
|
||||
2. yarn
|
||||
3. zkutil (`brew install rust && cargo install zkutil`)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
include "../node_modules/circomlib/circuits/poseidon.circom";
|
||||
include "../node_modules/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/poseidon.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/bitify.circom";
|
||||
|
||||
// Computes Poseidon([left, right])
|
||||
template HashLeftRight() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
include "../node_modules/circomlib/circuits/poseidon.circom";
|
||||
include "../node_modules/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/circomlib/circuits/comparators.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/poseidon.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/comparators.circom";
|
||||
include "./Utils.circom";
|
||||
include "./MerkleTree.circom";
|
||||
include "./MerkleTreeUpdater.circom";
|
||||
|
@ -1,5 +1,5 @@
|
||||
include "../node_modules/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/circomlib/circuits/pedersen.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/pedersen.circom";
|
||||
|
||||
// computes Pedersen(nullifier + secret)
|
||||
template TornadoCommitmentHasher() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
include "../node_modules/circomlib/circuits/poseidon.circom";
|
||||
include "../node_modules/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/poseidon.circom";
|
||||
include "../node_modules/@tornado/circomlib/circuits/bitify.circom";
|
||||
include "./Utils.circom";
|
||||
include "./MerkleTree.circom";
|
||||
include "./MerkleTreeUpdater.circom";
|
||||
|
@ -5,7 +5,7 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/IVerifier.sol";
|
||||
import "./interfaces/IRewardSwap.sol";
|
||||
import "tornado-trees/contracts/TornadoTrees.sol";
|
||||
import "@tornado/trees/contracts/TornadoTrees.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/math/SafeMath.sol";
|
||||
import "torn-token/contracts/ENS.sol";
|
||||
@ -105,11 +105,9 @@ contract Miner is EnsResolve {
|
||||
|
||||
_setRates(_rates);
|
||||
// prettier-ignore
|
||||
_setVerifiers([
|
||||
IVerifier(resolve(_verifiers[0])),
|
||||
IVerifier(resolve(_verifiers[1])),
|
||||
IVerifier(resolve(_verifiers[2]))
|
||||
]);
|
||||
_setVerifiers(
|
||||
[IVerifier(resolve(_verifiers[0])), IVerifier(resolve(_verifiers[1])), IVerifier(resolve(_verifiers[2]))]
|
||||
);
|
||||
}
|
||||
|
||||
function reward(bytes memory _proof, RewardArgs memory _args) public {
|
||||
@ -239,15 +237,15 @@ contract Miner is EnsResolve {
|
||||
// ------VIEW-------
|
||||
|
||||
/**
|
||||
@dev Whether the root is present in the root history
|
||||
*/
|
||||
* @dev Whether the root is present in the root history
|
||||
*/
|
||||
function isKnownAccountRoot(bytes32 _root, uint256 _index) public view returns (bool) {
|
||||
return _root != 0 && accountRoots[_index % ACCOUNT_ROOT_HISTORY_SIZE] == _root;
|
||||
}
|
||||
|
||||
/**
|
||||
@dev Returns the last root
|
||||
*/
|
||||
* @dev Returns the last root
|
||||
*/
|
||||
function getLastAccountRoot() public view returns (bytes32) {
|
||||
return accountRoots[accountCount % ACCOUNT_ROOT_HISTORY_SIZE];
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.6.0;
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
@ -13,15 +13,25 @@ contract TornadoProxy {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
event EncryptedNote(address indexed sender, bytes encryptedNote);
|
||||
enum InstanceState { Disabled, Enabled, Mineable }
|
||||
event InstanceStateUpdated(ITornadoInstance indexed instance, InstanceState state);
|
||||
event TornadoTreesUpdated(ITornadoTrees addr);
|
||||
|
||||
enum InstanceState { DISABLED, ENABLED, MINEABLE }
|
||||
|
||||
struct Instance {
|
||||
address instance;
|
||||
bool isERC20;
|
||||
IERC20 token;
|
||||
InstanceState state;
|
||||
}
|
||||
|
||||
struct Tornado {
|
||||
ITornadoInstance addr;
|
||||
Instance instance;
|
||||
}
|
||||
|
||||
ITornadoTrees public tornadoTrees;
|
||||
address public immutable governance;
|
||||
mapping(ITornadoInstance => InstanceState) public instances;
|
||||
mapping(ITornadoInstance => Instance) public instances;
|
||||
|
||||
modifier onlyGovernance() {
|
||||
require(msg.sender == governance, "Not authorized");
|
||||
@ -31,13 +41,13 @@ contract TornadoProxy {
|
||||
constructor(
|
||||
address _tornadoTrees,
|
||||
address _governance,
|
||||
Instance[] memory _instances
|
||||
Tornado[] memory _instances
|
||||
) public {
|
||||
tornadoTrees = ITornadoTrees(_tornadoTrees);
|
||||
governance = _governance;
|
||||
|
||||
for (uint256 i = 0; i < _instances.length; i++) {
|
||||
instances[ITornadoInstance(_instances[i].instance)] = _instances[i].state;
|
||||
_updateInstance(_instances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,11 +55,16 @@ contract TornadoProxy {
|
||||
ITornadoInstance _tornado,
|
||||
bytes32 _commitment,
|
||||
bytes calldata _encryptedNote
|
||||
) external payable {
|
||||
require(instances[_tornado] != InstanceState.Disabled, "The instance is not supported");
|
||||
) public payable virtual {
|
||||
Instance memory instance = instances[_tornado];
|
||||
require(instance.state != InstanceState.DISABLED, "The instance is not supported");
|
||||
|
||||
if (instance.isERC20) {
|
||||
instance.token.safeTransferFrom(msg.sender, address(this), _tornado.denomination());
|
||||
}
|
||||
_tornado.deposit{ value: msg.value }(_commitment);
|
||||
if (instances[_tornado] == InstanceState.Mineable) {
|
||||
|
||||
if (instance.state == InstanceState.MINEABLE) {
|
||||
tornadoTrees.registerDeposit(address(_tornado), _commitment);
|
||||
}
|
||||
emit EncryptedNote(msg.sender, _encryptedNote);
|
||||
@ -64,42 +79,66 @@ contract TornadoProxy {
|
||||
address payable _relayer,
|
||||
uint256 _fee,
|
||||
uint256 _refund
|
||||
) external payable {
|
||||
require(instances[_tornado] != InstanceState.Disabled, "The instance is not supported");
|
||||
) public payable virtual {
|
||||
Instance memory instance = instances[_tornado];
|
||||
require(instance.state != InstanceState.DISABLED, "The instance is not supported");
|
||||
|
||||
_tornado.withdraw{ value: msg.value }(_proof, _root, _nullifierHash, _recipient, _relayer, _fee, _refund);
|
||||
if (instances[_tornado] == InstanceState.Mineable) {
|
||||
if (instance.state == InstanceState.MINEABLE) {
|
||||
tornadoTrees.registerWithdrawal(address(_tornado), _nullifierHash);
|
||||
}
|
||||
}
|
||||
|
||||
function updateInstance(ITornadoInstance _instance, InstanceState _state) external onlyGovernance {
|
||||
instances[_instance] = _state;
|
||||
function backupNotes(bytes[] calldata _encryptedNotes) external virtual {
|
||||
for (uint256 i = 0; i < _encryptedNotes.length; i++) {
|
||||
emit EncryptedNote(msg.sender, _encryptedNotes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function setTornadoTreesContract(address _instance) external onlyGovernance {
|
||||
tornadoTrees = ITornadoTrees(_instance);
|
||||
function updateInstance(Tornado calldata _tornado) external virtual onlyGovernance {
|
||||
_updateInstance(_tornado);
|
||||
}
|
||||
|
||||
function setTornadoTreesContract(ITornadoTrees _tornadoTrees) external virtual onlyGovernance {
|
||||
tornadoTrees = _tornadoTrees;
|
||||
emit TornadoTreesUpdated(_tornadoTrees);
|
||||
}
|
||||
|
||||
/// @dev Method to claim junk and accidentally sent tokens
|
||||
function rescueTokens(
|
||||
IERC20 _token,
|
||||
address payable _to,
|
||||
uint256 _balance
|
||||
) external onlyGovernance {
|
||||
uint256 _amount
|
||||
) external virtual onlyGovernance {
|
||||
require(_to != address(0), "TORN: can not send to zero address");
|
||||
|
||||
if (_token == IERC20(0)) {
|
||||
// for Ether
|
||||
uint256 totalBalance = address(this).balance;
|
||||
uint256 balance = _balance == 0 ? totalBalance : Math.min(totalBalance, _balance);
|
||||
uint256 balance = Math.min(totalBalance, _amount);
|
||||
_to.transfer(balance);
|
||||
} else {
|
||||
// any other erc20
|
||||
uint256 totalBalance = _token.balanceOf(address(this));
|
||||
uint256 balance = _balance == 0 ? totalBalance : Math.min(totalBalance, _balance);
|
||||
uint256 balance = Math.min(totalBalance, _amount);
|
||||
require(balance > 0, "TORN: trying to send 0 balance");
|
||||
_token.safeTransfer(_to, balance);
|
||||
}
|
||||
}
|
||||
|
||||
function _updateInstance(Tornado memory _tornado) internal {
|
||||
instances[_tornado.addr] = _tornado.instance;
|
||||
if (_tornado.instance.isERC20) {
|
||||
IERC20 token = IERC20(_tornado.addr.token());
|
||||
require(token == _tornado.instance.token, "Incorrect token");
|
||||
uint256 allowance = token.allowance(address(this), address(_tornado.addr));
|
||||
|
||||
if (_tornado.instance.state != InstanceState.DISABLED && allowance == 0) {
|
||||
token.safeApprove(address(_tornado.addr), uint256(-1));
|
||||
} else if (_tornado.instance.state == InstanceState.DISABLED && allowance != 0) {
|
||||
token.safeApprove(address(_tornado.addr), 0);
|
||||
}
|
||||
}
|
||||
emit InstanceStateUpdated(_tornado.addr, _tornado.instance.state);
|
||||
}
|
||||
}
|
||||
|
36
contracts/TornadoProxyLight.sol
Normal file
36
contracts/TornadoProxyLight.sol
Normal file
@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.6.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import "./interfaces/ITornadoInstance.sol";
|
||||
|
||||
contract TornadoProxyLight {
|
||||
event EncryptedNote(address indexed sender, bytes encryptedNote);
|
||||
|
||||
function deposit(
|
||||
ITornadoInstance _tornado,
|
||||
bytes32 _commitment,
|
||||
bytes calldata _encryptedNote
|
||||
) external payable {
|
||||
_tornado.deposit{ value: msg.value }(_commitment);
|
||||
emit EncryptedNote(msg.sender, _encryptedNote);
|
||||
}
|
||||
|
||||
function withdraw(
|
||||
ITornadoInstance _tornado,
|
||||
bytes calldata _proof,
|
||||
bytes32 _root,
|
||||
bytes32 _nullifierHash,
|
||||
address payable _recipient,
|
||||
address payable _relayer,
|
||||
uint256 _fee,
|
||||
uint256 _refund
|
||||
) external payable {
|
||||
_tornado.withdraw{ value: msg.value }(_proof, _root, _nullifierHash, _recipient, _relayer, _fee, _refund);
|
||||
}
|
||||
|
||||
function backupNotes(bytes[] calldata _encryptedNotes) external {
|
||||
for (uint256 i = 0; i < _encryptedNotes.length; i++) {
|
||||
emit EncryptedNote(msg.sender, _encryptedNotes[i]);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.6.0;
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
interface ITornadoInstance {
|
||||
function token() external view returns (address);
|
||||
|
||||
function denomination() external view returns (uint256);
|
||||
|
||||
function deposit(bytes32 commitment) external payable;
|
||||
|
||||
function withdraw(
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.6.0;
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
interface ITornadoTrees {
|
||||
function registerDeposit(address instance, bytes32 commitment) external;
|
||||
|
@ -3,4 +3,4 @@
|
||||
pragma solidity ^0.6.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "tornado-trees/contracts/mocks/TornadoTreesMock.sol";
|
||||
import "@tornado/trees/contracts/mocks/TornadoTreesMock.sol";
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "tornado-trees/contracts/mocks/TornadoTreesV1Mock.sol";
|
||||
import "@tornado/trees/contracts/mocks/TornadoTreesV1Mock.sol";
|
||||
|
18
package.json
18
package.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "tornado-anonymity-mining",
|
||||
"version": "2.0.2",
|
||||
"name": "@tornado/anonymity-mining",
|
||||
"version": "2.1.5",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/tornadocash/tornado-anonymity-mining.git",
|
||||
"repository": "https://git.tornado.ws/tornado-packages/anonymity-mining.git",
|
||||
"author": "Tornadocash team <hello@tornado.cash>",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
@ -47,13 +47,13 @@
|
||||
"truffle-plugin-verify": "^0.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"circomlib": "git+https://github.com/tornadocash/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
|
||||
"@tornado/circomlib": "^0.0.21",
|
||||
"@tornado/fixed-merkle-tree": "0.3.4",
|
||||
"@tornado/snarkjs": "0.1.20",
|
||||
"@tornado/trees": "^0.0.11",
|
||||
"@tornado/websnark": "^0.0.4",
|
||||
"decimal.js": "^10.2.0",
|
||||
"eth-sig-util": "^2.5.3",
|
||||
"fixed-merkle-tree": "^0.3.4",
|
||||
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
|
||||
"tornado-trees": "^0.0.7",
|
||||
"web3": "^1.2.11",
|
||||
"websnark": "git+https://github.com/tornadocash/websnark.git#86a526718cd6f6f5d31bdb1fe26a9ec8819f633e"
|
||||
"web3": "^1.2.11"
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,6 @@ npx circom circuits/$1.circom -o build/circuits/$1.json
|
||||
npx snarkjs info -c build/circuits/$1.json
|
||||
zkutil setup -c build/circuits/$1.json -p build/circuits/$1.params
|
||||
zkutil export-keys -c build/circuits/$1.json -p build/circuits/$1.params --pk build/circuits/$1_proving_key.json --vk build/circuits/$1_verification_key.json
|
||||
node node_modules/websnark/tools/buildpkey.js -i build/circuits/$1_proving_key.json -o build/circuits/$1_proving_key.bin
|
||||
node node_modules/@tornado/websnark/tools/buildpkey.js -i build/circuits/$1_proving_key.json -o build/circuits/$1_proving_key.bin
|
||||
zkutil generate-verifier -p build/circuits/$1.params -v build/circuits/${1}Verifier.sol
|
||||
sed -i.bak "s/contract Verifier/contract ${1}Verifier/g" build/circuits/${1}Verifier.sol
|
||||
|
@ -11,9 +11,9 @@ const {
|
||||
RewardArgs,
|
||||
} = require('./utils')
|
||||
const Account = require('./account')
|
||||
const MerkleTree = require('fixed-merkle-tree')
|
||||
const websnarkUtils = require('websnark/src/utils')
|
||||
const buildGroth16 = require('websnark/src/groth16')
|
||||
const MerkleTree = require('@tornado/fixed-merkle-tree')
|
||||
const websnarkUtils = require('@tornado/websnark/src/utils')
|
||||
const buildGroth16 = require('@tornado/websnark/src/groth16')
|
||||
|
||||
const web3 = new Web3()
|
||||
|
||||
@ -131,7 +131,13 @@ class Controller {
|
||||
const newAccount = new Account({ amount: newAmount })
|
||||
|
||||
depositDataEvents = depositDataEvents || (await this._fetchDepositDataEvents())
|
||||
const depositLeaves = depositDataEvents.map((x) => poseidonHash([x.instance, x.hash, x.block]))
|
||||
const depositLeaves = depositDataEvents.map((x) => {
|
||||
if (x.poseidon) {
|
||||
return x.poseidon
|
||||
}
|
||||
|
||||
return poseidonHash([x.instance, x.hash, x.block])
|
||||
})
|
||||
const depositTree = new MerkleTree(this.merkleTreeHeight, depositLeaves, { hashFunction: poseidonHash2 })
|
||||
const depositItem = depositDataEvents.filter((x) => x.hash === toFixedHex(note.commitment))
|
||||
if (depositItem.length === 0) {
|
||||
@ -140,7 +146,13 @@ class Controller {
|
||||
const depositPath = depositTree.path(depositItem[0].index)
|
||||
|
||||
withdrawalDataEvents = withdrawalDataEvents || (await this._fetchWithdrawalDataEvents())
|
||||
const withdrawalLeaves = withdrawalDataEvents.map((x) => poseidonHash([x.instance, x.hash, x.block]))
|
||||
const withdrawalLeaves = withdrawalDataEvents.map((x) => {
|
||||
if (x.poseidon) {
|
||||
return x.poseidon
|
||||
}
|
||||
|
||||
return poseidonHash([x.instance, x.hash, x.block])
|
||||
})
|
||||
const withdrawalTree = new MerkleTree(this.merkleTreeHeight, withdrawalLeaves, {
|
||||
hashFunction: poseidonHash2,
|
||||
})
|
||||
|
@ -25,11 +25,10 @@ class Note {
|
||||
}
|
||||
|
||||
static fromString(note, instance, depositBlock, withdrawalBlock) {
|
||||
note = note.split('-')
|
||||
const [, currency, amount, netId] = note
|
||||
const hexNote = note[4].slice(2)
|
||||
const nullifier = new BN(hexNote.slice(0, 62), 16, 'le')
|
||||
const secret = new BN(hexNote.slice(62), 16, 'le')
|
||||
const [, currency, amount, netId, noteHex] = note.split('-')
|
||||
const noteBuff = Buffer.from(noteHex.slice(2), 'hex')
|
||||
const nullifier = new BN(noteBuff.slice(0, 31), 16, 'le')
|
||||
const secret = new BN(noteBuff.slice(31), 16, 'le')
|
||||
return new Note({
|
||||
secret,
|
||||
nullifier,
|
||||
|
@ -1,10 +1,10 @@
|
||||
const crypto = require('crypto')
|
||||
const Decimal = require('decimal.js')
|
||||
const { bigInt } = require('snarkjs')
|
||||
const { bigInt } = require('@tornado/snarkjs')
|
||||
const { toBN, soliditySha3 } = require('web3-utils')
|
||||
const Web3 = require('web3')
|
||||
const web3 = new Web3()
|
||||
const { babyJub, pedersenHash, mimcsponge, poseidon } = require('circomlib')
|
||||
const { babyJub, pedersenHash, mimcsponge, poseidon } = require('@tornado/circomlib')
|
||||
|
||||
const RewardExtData = {
|
||||
RewardExtData: {
|
||||
|
@ -34,7 +34,7 @@ const provingKeys = {
|
||||
withdrawProvingKey: fs.readFileSync('./build/circuits/Withdraw_proving_key.bin').buffer,
|
||||
treeUpdateProvingKey: fs.readFileSync('./build/circuits/TreeUpdate_proving_key.bin').buffer,
|
||||
}
|
||||
const MerkleTree = require('fixed-merkle-tree')
|
||||
const MerkleTree = require('@tornado/fixed-merkle-tree')
|
||||
|
||||
// Set time to beginning of a second
|
||||
async function timeReset() {
|
||||
@ -225,6 +225,22 @@ contract('Miner', (accounts) => {
|
||||
note.commitment.should.be.eq.BN(
|
||||
toBN('0x1a08fd10dae9806ce25b62582e44d237c1cb9f8d6bf73e756f18d0e5d7a7351a'),
|
||||
)
|
||||
const note1 = Note.fromString(
|
||||
'tornado-eth-1-5-0x00b9787ae8b877cc612acfc3d46eb1303c618ef386cb4383b75be5b300ac9b94818f3f7a589b4667612e879dbfd44198231c86aaa412a3770fd86d8fc045',
|
||||
'0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f',
|
||||
10,
|
||||
15,
|
||||
)
|
||||
note1.secret.should.be.eq.BN(toBN('0x45c08f6dd80f77a312a4aa861c239841d4bf9d872e6167469b587a3f8f8194'))
|
||||
note1.nullifier.should.be.eq.BN(
|
||||
toBN('0x9bac00b3e55bb78343cb86f38e613c30b16ed4c3cf2a61cc77b8e87a78b900'),
|
||||
)
|
||||
note1.nullifierHash.should.be.eq.BN(
|
||||
toBN('0x1892018e434ed0476992c7e05e6022b69eacf746a978191117194d180104aed1'),
|
||||
)
|
||||
note1.commitment.should.be.eq.BN(
|
||||
toBN('0x270a865e2bf7de26b0a6de08c527f4d13e2b49026f6aaeeea0866a9dd39e19f6'),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user