I made a solidity function that allow a user to send multiple transactions with the same nonce as a singleton Tx signer:
function multipleTransferPreSigned
(
bytes[] _signature,
address[] _to,
uint[] _value,
uint[] _fee,
uint256 _nonce
)
public
returns (bool)
{
for(uint256 i=0; i < _signature.length; i++)
{
require(_to[i] != address(0));
require(interfaceData.getSignatures(_signature[i]) == false);
bytes32 hashedTx = transferPreSignedHashing(address(this), _to[i],
_value[i], _fee[i], _nonce + i);
address from = recover(hashedTx, _signature[i]);
require(from != address(0));
balances[from] = balances[from].sub(_value[i]).sub(_fee[i]);
balances[_to[i]] = balances[_to[i]].add(_value[i]);
balances[msg.sender] = balances[msg.sender].add(_fee[i]);
interfaceData.setSignatures(_signature[i], true);
signatures[_signature] = true;
emit Transfer(from, _to[i], _value[i]);
emit Transfer(from, msg.sender, _fee[i]);
emit TransferPreSigned(from, _to[i], msg.sender, _value[i], _fee[i]);
}
return true;
}
when I pass the arguments using remix IDE like this:
["0x7cd81c609d1b65cdaed5c09527bf2bd075279a03ce5c0b7474655a91784a54b36e35e903f754bfc3411ae64f9b1627bf81c5a93c77441c2ba0822f61ed2707e51c", "0xf62e24934659fe88bf28de2dc8c37972c30351238de8341414780c7c37902a9b1f02b51e303618eec0be11d0ae5abf57e4aa39aaae4aed4413016d04c732abe31c"]
["0x27e739f9dF8135fD1946b0b5584BcE49E22000af", "0x0356a6cfcf3fd04ea88044a59458abb982aa9d96"]
["2000000000000000000", "2000000000000000000"]
["1000000000000000000", "1000000000000000000"]
628
the function working as expected. But when I use Nethereum I do not understand how to pass the arguments. It doesn't work.
My C# code:
public async Task<string> MultipleTransferPreSignedAsync(List<string> fromPK, List<string> to, List<int> amount, List<int> fee, CancellationToken token)
{
Account SpitballAccountt = new Account(SpitballPrivateKey);
var web3 = new Web3(SpitballAccountt);
List<BigInteger> amountList = new List<BigInteger>();
List<BigInteger> feeList = new List<BigInteger>();
List<byte[]> sigList = new List<byte[]>();
var txCount = await web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(GetAddress(SpitballPrivateKey));
var nonce = txCount.Value;
for (int i = 0; i < fromPK.Count; i++)
{
var amountTransformed = new BigInteger(amount[i] * FromWei);
amountList.Add(amountTransformed);
var feeTransformed = new BigInteger(fee[i] * FromWei);
feeList.Add(feeTransformed);
nonce = txCount.Value + i;
string str = "48664c16"
+ ContractAddress.RemoveHexPrefix()
+ to[i].RemoveHexPrefix()
+ amountTransformed.ToString("X64")
+ feeTransformed.ToString("X64")
+ nonce.ToString("X64");
var byteStr = HexByteConvertorExtensions.HexToByteArray(str);
var sha3 = new Nethereum.Util.Sha3Keccack();
var res = sha3.CalculateHash(byteStr);
var messageSigner = new MessageSigner();
sigList.Add(messageSigner.Sign(res, fromPK[i]).HexToByteArray());
}
nonce = txCount.Value;
var function = await GetFunctionAsync("multipleTransferPreSigned", token).ConfigureAwait(false);
var receiptFirstAmountSend = await function.SendTransactionAndWaitForReceiptAsync(SpitballPrivateKey, MaxGas, token, sigList.ToArray(), to.ToArray(), amountList.ToArray(), feeList.ToArray(), nonce).ConfigureAwait(false);
var contract = await GetContractAsync(web3, token);
var bidAddedEventLog = contract.GetEvent("TransferPreSigned");
var filterInput =
bidAddedEventLog.CreateFilterInput(new BlockParameter(receiptFirstAmountSend.BlockNumber), BlockParameter.CreateLatest());
var logs = await bidAddedEventLog.GetAllChanges<TransferPreSignedDTO>(filterInput);
return receiptFirstAmountSend.BlockHash;
}
public static async Task<TransactionReceipt> SendTransactionAndWaitForReceiptAsync(this Function function, string privateKey, double maxGas,
CancellationToken receiptRequestCancellationToken, params object[] functionInput)
{
var gas = new HexBigInteger((BigInteger)maxGas);
var publicAddress = Web3.GetAddressFromPrivateKey(privateKey);
using (var tokenSource = CancellationTokenSource.CreateLinkedTokenSource(receiptRequestCancellationToken))
{
return await function.SendTransactionAndWaitForReceiptAsync(publicAddress, gas, null,
tokenSource, functionInput).ConfigureAwait(false);
}
}
Any help will be great. Thanks.