diff --git a/src/Stratis.Bitcoin.Features.Interop/ETHClient/ContractSource/WrappedToken.sol b/src/Stratis.Bitcoin.Features.Interop/ETHClient/ContractSource/WrappedToken.sol new file mode 100644 index 0000000000..bb0f32447c --- /dev/null +++ b/src/Stratis.Bitcoin.Features.Interop/ETHClient/ContractSource/WrappedToken.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.0; + +// Importing dependencies +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/access/Ownable.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/cryptography/ECDSA.sol"; + +contract WrappedToken is ERC20, Ownable { + string public constant CONTRACT_NAME = "WrappedToken"; + string public constant CONTRACT_VERSION = "v1"; + + mapping (string => string) public withdrawalAddresses; + mapping (uint128 => bool) public uniqueNumberUsed; + mapping (address => bool) public isBlacklisted; + + // Constructor initializes the ERC20 token + constructor(string memory tokenName, string memory tokenSymbol, uint256 initialSupply) public ERC20(tokenName, tokenSymbol) { + _mint(msg.sender, initialSupply); + } + + // Allows only the owner to mint new tokens + function mint(address account, uint256 amount) public onlyOwner { + _mint(account, amount); + } + + // Allows users to burn tokens and specify a withdrawal address + function burn(uint256 amount, string memory tokenAddress, string memory burnId) public { + _burn(msg.sender, amount); + string memory key = string(abi.encodePacked(msg.sender, " ", burnId)); + withdrawalAddresses[key] = tokenAddress; + } + + // Allows users to burn tokens from an approved address + function burnFrom(address account, uint256 amount, string memory tokenAddress, string memory burnId) public { + uint256 decreasedAllowance = allowance(account, msg.sender).sub(amount, "ERC20: burn amount exceeds allowance"); + _approve(account, msg.sender, decreasedAllowance); + _burn(account, amount); + string memory key = string(abi.encodePacked(msg.sender, " ", burnId)); + withdrawalAddresses[key] = tokenAddress; + } + + // Allows the owner to add addresses to the blacklist + function addToBlackList(address[] calldata addresses) external onlyOwner { + for (uint256 i = 0; i < addresses.length; ++i) { + isBlacklisted[addresses[i]] = true; + } + } + + // Allows the owner to remove addresses from the blacklist + function removeFromBlackList(address account) external onlyOwner { + isBlacklisted[account] = false; + } + + // Checks if the address is blacklisted before any token transfer + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { + super._beforeTokenTransfer(from, to, amount); + require(!isBlacklisted[from] && !isBlacklisted[to], "This address is blacklisted"); + } + + // Perform a cross-chain transfer using delegated transfer with metadata + function _transferForNetwork( + address fromAddr, + string memory targetNetwork, + string memory targetAddress, + string memory metadata, + uint256 transferAmount + ) internal { + _beforeTokenTransfer(fromAddr, interflux, transferAmount); + _transfer(fromAddr, interflux, transferAmount); + emit CrossChainTransferLog(targetAddress, targetNetwork); + emit MetadataLog(metadata); + } + + function transferForNetwork( + string memory targetNetwork, + string memory targetAddress, + string memory metadata, + uint256 transferAmount + ) public { + _transferForNetwork(msg.sender, targetNetwork, targetAddress, metadata, transferAmount); + } + + // Perform a cross-chain transfer using delegated transfer with metadata + function delegatedTransferForNetwork( + uint128 uniqueNumber, + address fromAddr, + string memory targetNetwork, + string memory targetAddress, + string memory metadata, + uint32 amount, + uint8 amountCents, + bytes memory signature + ) public { + require(!uniqueNumberUsed[uniqueNumber], "Unique number already used"); + uniqueNumberUsed[uniqueNumber] = true; + string memory token = symbol(); + bytes32 dataHash = keccak256(abi.encode(uniqueNumber, keccak256(bytes(token)), fromAddr, keccak256(bytes(targetNetwork)), keccak256(bytes(targetAddress)), keccak256(bytes(metadata)), amount, amountCents)); + bytes32 domainSeparator = _getDomainSeparator(); + bytes32 eip712DataHash = keccak256(abi.encodePacked("\x19\x01", domainSeparator, dataHash)); + address recoveredAddress = ECDSA.recover(eip712DataHash, signature); + require(fromAddr == recoveredAddress, "The 'fromAddr' is not the signer"); + uint256 decimalsFactor = uint256(10) ** decimals(); + uint256 transferAmount = uint256(amount) * decimalsFactor + uint256(amountCents) * (decimalsFactor / 100); + + _transferForNetwork(fromAddr, targetNetwork, targetAddress, metadata, transferAmount); + } + + // Event definitions + event CrossChainTransferLog(string account, string network); + event MetadataLog(string metadata); + + // Ethereum Interflux address variable + address public interflux; + + // Method to update the Ethereum Interflux address + function setInterflux(address newAddress) public onlyOwner { + interflux = newAddress; + } + + function _getDomainSeparator() internal view returns(bytes32 domainSeparator) { + uint chainId; + assembly { + chainId := chainid() + } + + return keccak256(abi.encode(keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(abi.encodePacked(CONTRACT_NAME)), keccak256(abi.encodePacked(CONTRACT_VERSION)), chainId, address(this))); + } +} diff --git a/src/Stratis.Bitcoin.Features.Interop/ETHClient/WrappedToken.cs b/src/Stratis.Bitcoin.Features.Interop/ETHClient/WrappedToken.cs new file mode 100644 index 0000000000..f728f8f321 --- /dev/null +++ b/src/Stratis.Bitcoin.Features.Interop/ETHClient/WrappedToken.cs @@ -0,0 +1,734 @@ +using System.Numerics; +using System.Threading.Tasks; +using Nethereum.ABI.FunctionEncoding.Attributes; +using Nethereum.Contracts; +using Nethereum.Contracts.ContractHandlers; +using Nethereum.Contracts.CQS; +using Nethereum.Hex.HexTypes; +using Nethereum.RPC.Eth.DTOs; +using Nethereum.Util; +using Nethereum.Web3; + +namespace Stratis.Bitcoin.Features.Interop.ETHClient2 +{ + public class WrappedTokenDeployment : ContractDeploymentMessage + { + public static string BYTECODE = + "0x60806040523480156200001157600080fd5b506040516200302338038062003023833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b838201915060208201858111156200012c57600080fd5b82518660018202830111640100000000821117156200014a57600080fd5b8083526020830192505050908051906020019080838360005b838110156200018057808201518184015260208101905062000163565b50505050905090810190601f168015620001ae5780820380516001836020036101000a031916815260200191505b506040526020018051906020019092919050505082828160039080519060200190620001dc92919062000689565b508060049080519060200190620001f592919062000689565b506012600560006101000a81548160ff021916908360ff1602179055505050600062000226620002e060201b60201c565b905080600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620002d73382620002e860201b60201c565b50505062000738565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200038c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b620003a060008383620004c660201b60201c565b620003bc81600254620005fb60201b620020ea1790919060201c565b6002819055506200041a816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054620005fb60201b620020ea1790919060201c565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b620004de8383836200068460201b6200266d1760201c565b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015620005835750600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b620005f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f54686973206164647265737320697320626c61636b6c6973746564000000000081525060200191505060405180910390fd5b505050565b6000808284019050838110156200067a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620006cc57805160ff1916838001178555620006fd565b82800160010185558215620006fd579182015b82811115620006fc578251825591602001919060010190620006df565b5b5090506200070c919062000710565b5090565b6200073591905b808211156200073157600081600090555060010162000717565b5090565b90565b6128db80620007486000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c8063715018a6116100b8578063ba211db01161007c578063ba211db01461063c578063bd65278714610798578063dd62ed3e14610914578063f2fde38b1461098c578063f306f6cb146109d0578063ff89757014610b0457610137565b8063715018a6146104995780638da5cb5b146104a357806395d89b41146104ed578063a457c2d714610570578063a9059cbb146105d657610137565b8063313ce567116100ff578063313ce56714610325578063395093511461034957806340c10f19146103af5780634a49ac4c146103fd57806370a082311461044157610137565b806306fdde031461013c578063095ea7b3146101bf57806318160ddd146102255780631cdd3be31461024357806323b872dd1461029f575b600080fd5b610144610b7d565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610184578082015181840152602081019050610169565b50505050905090810190601f1680156101b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61020b600480360360408110156101d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1f565b604051808215151515815260200191505060405180910390f35b61022d610c3d565b6040518082815260200191505060405180910390f35b6102856004803603602081101561025957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c47565b604051808215151515815260200191505060405180910390f35b61030b600480360360608110156102b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c67565b604051808215151515815260200191505060405180910390f35b61032d610d40565b604051808260ff1660ff16815260200191505060405180910390f35b6103956004803603604081101561035f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d57565b604051808215151515815260200191505060405180910390f35b6103fb600480360360408110156103c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e0a565b005b61043f6004803603602081101561041357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ee2565b005b6104836004803603602081101561045757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611007565b6040518082815260200191505060405180910390f35b6104a161104f565b005b6104ab6111da565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104f5611204565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561053557808201518184015260208101905061051a565b50505050905090810190601f1680156105625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105bc6004803603604081101561058657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506112a6565b604051808215151515815260200191505060405180910390f35b610622600480360360408110156105ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611373565b604051808215151515815260200191505060405180910390f35b6107966004803603606081101561065257600080fd5b81019080803590602001909291908035906020019064010000000081111561067957600080fd5b82018360208201111561068b57600080fd5b803590602001918460018302840111640100000000831117156106ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561071057600080fd5b82018360208201111561072257600080fd5b8035906020019184600183028401116401000000008311171561074457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611391565b005b610912600480360360808110156107ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156107f557600080fd5b82018360208201111561080757600080fd5b8035906020019184600183028401116401000000008311171561082957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561088c57600080fd5b82018360208201111561089e57600080fd5b803590602001918460018302840111640100000000831117156108c057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506114f4565b005b6109766004803603604081101561092a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116a5565b6040518082815260200191505060405180910390f35b6109ce600480360360208110156109a257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061172c565b005b610a89600480360360208110156109e657600080fd5b8101908080359060200190640100000000811115610a0357600080fd5b820183602082011115610a1557600080fd5b80359060200191846001830284011164010000000083111715610a3757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061193c565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ac9578082015181840152602081019050610aae565b50505050905090810190601f168015610af65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610b7b60048036036020811015610b1a57600080fd5b8101908080359060200190640100000000811115610b3757600080fd5b820183602082011115610b4957600080fd5b80359060200191846020830284011164010000000083111715610b6b57600080fd5b9091929391929390505050611a02565b005b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c155780601f10610bea57610100808354040283529160200191610c15565b820191906000526020600020905b815481529060010190602001808311610bf857829003601f168201915b5050505050905090565b6000610c33610c2c611b6a565b8484611b72565b6001905092915050565b6000600254905090565b60076020528060005260406000206000915054906101000a900460ff1681565b6000610c74848484611d69565b610d3584610c80611b6a565b610d30856040518060600160405280602881526020016127cb60289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610ce6611b6a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461202a9092919063ffffffff16565b611b72565b600190509392505050565b6000600560009054906101000a900460ff16905090565b6000610e00610d64611b6a565b84610dfb8560016000610d75611b6a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546120ea90919063ffffffff16565b611b72565b6001905092915050565b610e12611b6a565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ed4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610ede8282612172565b5050565b610eea611b6a565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611057611b6a565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611119576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561129c5780601f106112715761010080835404028352916020019161129c565b820191906000526020600020905b81548152906001019060200180831161127f57829003601f168201915b5050505050905090565b60006113696112b3611b6a565b846113648560405180606001604052806025815260200161288160259139600160006112dd611b6a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461202a9092919063ffffffff16565b611b72565b6001905092915050565b6000611387611380611b6a565b8484611d69565b6001905092915050565b6113a261139c611b6a565b84612339565b60603382604051602001808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401807f200000000000000000000000000000000000000000000000000000000000000081525060010182805190602001908083835b602083106114395780518252602082019150602081019050602083039250611416565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529050826006826040518082805190602001908083835b602083106114a75780518252602082019150602081019050602083039250611484565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902090805190602001906114ed929190612672565b5050505050565b6000611533846040518060600160405280602481526020016127f3602491396115248861151f611b6a565b6116a5565b61202a9092919063ffffffff16565b905061154785611541611b6a565b83611b72565b6115518585612339565b60603383604051602001808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401807f200000000000000000000000000000000000000000000000000000000000000081525060010182805190602001908083835b602083106115e857805182526020820191506020810190506020830392506115c5565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529050836006826040518082805190602001908083835b602083106116565780518252602082019150602081019050602083039250611633565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020908051906020019061169c929190612672565b50505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b611734611b6a565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146117f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561187c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061275d6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6006818051602081018201805184825260208301602085012081835280955050505050506000915090508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119fa5780601f106119cf576101008083540402835291602001916119fa565b820191906000526020600020905b8154815290600101906020018083116119dd57829003601f168201915b505050505081565b611a0a611b6a565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611acc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60005b82829050811015611b6557600160076000858585818110611aec57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550806001019050611acf565b505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611bf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061285d6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611c7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806127836022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611def576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806128386025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e75576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127186023913960400191505060405180910390fd5b611e808383836124fd565b611eeb816040518060600160405280602681526020016127a5602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461202a9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611f7e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546120ea90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906120d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561209c578082015181840152602081019050612081565b50505050905090810190601f1680156120c95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015612168576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b612221600083836124fd565b612236816002546120ea90919063ffffffff16565b60028190555061228d816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546120ea90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806128176021913960400191505060405180910390fd5b6123cb826000836124fd565b6124368160405180606001604052806022815260200161273b602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461202a9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061248d8160025461262390919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b61250883838361266d565b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156125ac5750600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b61261e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f54686973206164647265737320697320626c61636b6c6973746564000000000081525060200191505060405180910390fd5b505050565b600061266583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061202a565b905092915050565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106126b357805160ff19168380011785556126e1565b828001600101855582156126e1579182015b828111156126e05782518255916020019190600101906126c5565b5b5090506126ee91906126f2565b5090565b61271491905b808211156127105760008160009055506001016126f8565b5090565b9056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212208257b60e1e63956e9d349bc7d44d3b3eef8885b643e61c16bf7453108c360e3264736f6c63430006000033"; + + public WrappedTokenDeployment() : base(BYTECODE) + { + } + + [Parameter("string", "tokenName")] + public string TokenName { get; set; } + + [Parameter("string", "tokenSymbol")] + public string TokenSymbol { get; set; } + + [Parameter("uint256", "initialSupply")] + public BigInteger InitialSupply { get; set; } + } + + [Function("balanceOf", "uint256")] + public class BalanceOfFunction : FunctionMessage + { + [Parameter("address", "_owner", 1)] + public string Owner { get; set; } + } + + [FunctionOutput] + public class BalanceOfOutputDTO : IFunctionOutputDTO + { + [Parameter("uint256", "balance", 1)] + public BigInteger Balance { get; set; } + } + + [Function("transfer", "bool")] + public class TransferFunction : FunctionMessage + { + [Parameter("address", "_to", 1)] + public string To { get; set; } + + [Parameter("uint256", "_value", 2)] + public BigInteger TokenAmount { get; set; } + } + + [Event("Transfer")] + public class TransferEventDTO : IEventDTO + { + [Parameter("address", "_from", 1, true)] + public string From { get; set; } + + [Parameter("address", "_to", 2, true)] + public string To { get; set; } + + [Parameter("uint256", "_value", 3, false)] + public BigInteger Value { get; set; } + } + + [Function("owner", "address")] + public class OwnerFunction : FunctionMessage + { + } + + [Function("transferOwnership")] + public class TransferOwnershipFunction : FunctionMessage + { + [Parameter("address", "newOwner", 1)] + public string NewOwner { get; set; } + } + + [Function("withdrawalAddresses", "string")] + public class WithdrawalAddressesFunction : FunctionMessage + { + [Parameter("address", "", 1)] + public string Address { get; set; } + } + + [Function("mint")] + public class MintFunction : FunctionMessage + { + [Parameter("address", "account", 1)] + public string Account { get; set; } + + [Parameter("uint256", "amount", 2)] + public BigInteger Amount { get; set; } + } + + [Function("burn")] + public class BurnFunction : FunctionMessage + { + [Parameter("uint256", "amount", 1)] + public BigInteger Amount { get; set; } + + [Parameter("string", "tokenAddress", 2)] + public string TokenAddress { get; set; } + + [Parameter("string", "burnId", 3)] + public string BurnId { get; set; } + } + + [Function("addToBlackList")] + public class AddToBlackListFunction : FunctionMessage + { + [Parameter("address[]", "addresses", 1)] + public string Addresses { get; set; } + } + + [Function("removeFromBlackList")] + public class RemoveFromBlackListFunction : FunctionMessage + { + [Parameter("address", "account", 1)] + public string Address { get; set; } + } + + public class WrappedToken + { + public static async Task DeployContractAsync(Web3 web3, BigInteger totalSupply) + { + var deploymentMessage = new WrappedTokenDeployment() + { + InitialSupply = totalSupply + }; + + IContractDeploymentTransactionHandler deploymentHandler = web3.Eth.GetContractDeploymentHandler(); + TransactionReceipt transactionReceiptDeployment = await deploymentHandler.SendRequestAndWaitForReceiptAsync(deploymentMessage).ConfigureAwait(false); + string contractAddress = transactionReceiptDeployment.ContractAddress; + + return contractAddress; + } + + public static async Task GetErc20BalanceAsync(Web3 web3, string contractAddress, string addressToQuery) + { + var balanceOfFunctionMessage = new BalanceOfFunction() + { + Owner = addressToQuery + }; + + IContractQueryHandler balanceHandler = web3.Eth.GetContractQueryHandler(); + BigInteger balance = await balanceHandler.QueryAsync(contractAddress, balanceOfFunctionMessage).ConfigureAwait(false); + + return balance; + } + + public static async Task TransferAsync(Web3 web3, string contractAddress, string recipient, BigInteger amount, BigInteger gas, BigInteger gasPrice) + { + IContractTransactionHandler transferHandler = web3.Eth.GetContractTransactionHandler(); + + var transfer = new TransferFunction() + { + To = recipient, + TokenAmount = amount, + Gas = gas, + GasPrice = Web3.Convert.ToWei(gasPrice, UnitConversion.EthUnit.Gwei) + }; + + TransactionReceipt transactionTransferReceipt = await transferHandler.SendRequestAndWaitForReceiptAsync(contractAddress, transfer).ConfigureAwait(false); + + return transactionTransferReceipt.TransactionHash; + } + + public static async Task TransferOfflineAsync(Web3 web3, string contractAddress, string recipient, BigInteger amount, HexBigInteger nonce, BigInteger gas, BigInteger gasPrice, string fromAddress = null) + { + IContractTransactionHandler transferHandler = web3.Eth.GetContractTransactionHandler(); + + var transfer = new TransferFunction + { + To = recipient, + TokenAmount = amount, + // Nethereum internally calls its Ethereum client by default to set the GasPrice, Nonce and estimate the Gas, + // so if we want to sign the transaction for the contract completely offline we will need to set those values ourselves. + Nonce = nonce.Value, + Gas = gas, + GasPrice = Web3.Convert.ToWei(gasPrice, UnitConversion.EthUnit.Gwei) + }; + + if (fromAddress != null) + transfer.FromAddress = fromAddress; + + string result = await transferHandler.SignTransactionAsync(contractAddress, transfer).ConfigureAwait(false); + + return result; + } + + public static async Task TransferOwnershipAsync(Web3 web3, string contractAddress, string newOwner) + { + IContractTransactionHandler transferHandler = web3.Eth.GetContractTransactionHandler(); + + var transfer = new TransferOwnershipFunction() + { + NewOwner = newOwner + }; + + TransactionReceipt transactionTransferReceipt = await transferHandler.SendRequestAndWaitForReceiptAsync(contractAddress, transfer).ConfigureAwait(false); + + return transactionTransferReceipt.TransactionHash; + } + + public static async Task GetOwnerAsync(Web3 web3, string contractAddress) + { + var ownerFunctionMessage = new OwnerFunction() + { + }; + + IContractQueryHandler ownerHandler = web3.Eth.GetContractQueryHandler(); + string owner = await ownerHandler.QueryAsync(contractAddress, ownerFunctionMessage).ConfigureAwait(false); + + return owner; + } + + public static async Task GetDestinationAddressAsync(Web3 web3, string contractAddress, string addressToQuery) + { + var withdrawalAddressesFunctionMessage = new WithdrawalAddressesFunction() + { + Address = addressToQuery + }; + + IContractQueryHandler queryHandler = web3.Eth.GetContractQueryHandler(); + string destinationAddress = await queryHandler.QueryAsync(contractAddress, withdrawalAddressesFunctionMessage).ConfigureAwait(false); + + return destinationAddress; + } + + /* + "39509351": "increaseAllowance(address,uint256)", + "dd62ed3e": "allowance(address,address)", + "095ea7b3": "approve(address,uint256)", + "70a08231": "balanceOf(address)", + "7641e6f3": "burn(uint256,string)", + "979430d2": "burnFrom(address,uint256,string)", + "313ce567": "decimals()", + "a457c2d7": "decreaseAllowance(address,uint256)", + "40c10f19": "mint(address,uint256)", + "06fdde03": "name()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "95d89b41": "symbol()", + "18160ddd": "totalSupply()", + "a9059cbb": "transfer(address,uint256)", + "23b872dd": "transferFrom(address,address,uint256)", + "f2fde38b": "transferOwnership(address)", + "7e051867": "withdrawalAddresses(address)" + */ + + public static string ABI = @"[ + { + ""inputs"": [ + { + ""internalType"": ""string"", + ""name"": ""tokenName"", + ""type"": ""string"" + }, + { + ""internalType"": ""string"", + ""name"": ""tokenSymbol"", + ""type"": ""string"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""initialSupply"", + ""type"": ""uint256"" + } + ], + ""stateMutability"": ""nonpayable"", + ""type"": ""constructor"" + }, + { + ""anonymous"": false, + ""inputs"": [ + { + ""indexed"": true, + ""internalType"": ""address"", + ""name"": ""owner"", + ""type"": ""address"" + }, + { + ""indexed"": true, + ""internalType"": ""address"", + ""name"": ""spender"", + ""type"": ""address"" + }, + { + ""indexed"": false, + ""internalType"": ""uint256"", + ""name"": ""value"", + ""type"": ""uint256"" + } + ], + ""name"": ""Approval"", + ""type"": ""event"" + }, + { + ""anonymous"": false, + ""inputs"": [ + { + ""indexed"": true, + ""internalType"": ""address"", + ""name"": ""previousOwner"", + ""type"": ""address"" + }, + { + ""indexed"": true, + ""internalType"": ""address"", + ""name"": ""newOwner"", + ""type"": ""address"" + } + ], + ""name"": ""OwnershipTransferred"", + ""type"": ""event"" + }, + { + ""anonymous"": false, + ""inputs"": [ + { + ""indexed"": true, + ""internalType"": ""address"", + ""name"": ""from"", + ""type"": ""address"" + }, + { + ""indexed"": true, + ""internalType"": ""address"", + ""name"": ""to"", + ""type"": ""address"" + }, + { + ""indexed"": false, + ""internalType"": ""uint256"", + ""name"": ""value"", + ""type"": ""uint256"" + } + ], + ""name"": ""Transfer"", + ""type"": ""event"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": """", + ""type"": ""address"" + } + ], + ""name"": ""_isBlacklisted"", + ""outputs"": [ + { + ""internalType"": ""bool"", + ""name"": """", + ""type"": ""bool"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address[]"", + ""name"": ""addresses"", + ""type"": ""address[]"" + } + ], + ""name"": ""addToBlackList"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""owner"", + ""type"": ""address"" + }, + { + ""internalType"": ""address"", + ""name"": ""spender"", + ""type"": ""address"" + } + ], + ""name"": ""allowance"", + ""outputs"": [ + { + ""internalType"": ""uint256"", + ""name"": """", + ""type"": ""uint256"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""spender"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""amount"", + ""type"": ""uint256"" + } + ], + ""name"": ""approve"", + ""outputs"": [ + { + ""internalType"": ""bool"", + ""name"": """", + ""type"": ""bool"" + } + ], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""account"", + ""type"": ""address"" + } + ], + ""name"": ""balanceOf"", + ""outputs"": [ + { + ""internalType"": ""uint256"", + ""name"": """", + ""type"": ""uint256"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""uint256"", + ""name"": ""amount"", + ""type"": ""uint256"" + }, + { + ""internalType"": ""string"", + ""name"": ""tokenAddress"", + ""type"": ""string"" + }, + { + ""internalType"": ""string"", + ""name"": ""burnId"", + ""type"": ""string"" + } + ], + ""name"": ""burn"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""account"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""amount"", + ""type"": ""uint256"" + }, + { + ""internalType"": ""string"", + ""name"": ""tokenAddress"", + ""type"": ""string"" + }, + { + ""internalType"": ""string"", + ""name"": ""burnId"", + ""type"": ""string"" + } + ], + ""name"": ""burnFrom"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [], + ""name"": ""decimals"", + ""outputs"": [ + { + ""internalType"": ""uint8"", + ""name"": """", + ""type"": ""uint8"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""spender"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""subtractedValue"", + ""type"": ""uint256"" + } + ], + ""name"": ""decreaseAllowance"", + ""outputs"": [ + { + ""internalType"": ""bool"", + ""name"": """", + ""type"": ""bool"" + } + ], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""spender"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""addedValue"", + ""type"": ""uint256"" + } + ], + ""name"": ""increaseAllowance"", + ""outputs"": [ + { + ""internalType"": ""bool"", + ""name"": """", + ""type"": ""bool"" + } + ], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""account"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""amount"", + ""type"": ""uint256"" + } + ], + ""name"": ""mint"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [], + ""name"": ""name"", + ""outputs"": [ + { + ""internalType"": ""string"", + ""name"": """", + ""type"": ""string"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [], + ""name"": ""owner"", + ""outputs"": [ + { + ""internalType"": ""address"", + ""name"": """", + ""type"": ""address"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""account"", + ""type"": ""address"" + } + ], + ""name"": ""removeFromBlackList"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [], + ""name"": ""renounceOwnership"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [], + ""name"": ""symbol"", + ""outputs"": [ + { + ""internalType"": ""string"", + ""name"": """", + ""type"": ""string"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [], + ""name"": ""totalSupply"", + ""outputs"": [ + { + ""internalType"": ""uint256"", + ""name"": """", + ""type"": ""uint256"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""recipient"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""amount"", + ""type"": ""uint256"" + } + ], + ""name"": ""transfer"", + ""outputs"": [ + { + ""internalType"": ""bool"", + ""name"": """", + ""type"": ""bool"" + } + ], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""sender"", + ""type"": ""address"" + }, + { + ""internalType"": ""address"", + ""name"": ""recipient"", + ""type"": ""address"" + }, + { + ""internalType"": ""uint256"", + ""name"": ""amount"", + ""type"": ""uint256"" + } + ], + ""name"": ""transferFrom"", + ""outputs"": [ + { + ""internalType"": ""bool"", + ""name"": """", + ""type"": ""bool"" + } + ], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""address"", + ""name"": ""newOwner"", + ""type"": ""address"" + } + ], + ""name"": ""transferOwnership"", + ""outputs"": [], + ""stateMutability"": ""nonpayable"", + ""type"": ""function"" + }, + { + ""inputs"": [ + { + ""internalType"": ""string"", + ""name"": """", + ""type"": ""string"" + } + ], + ""name"": ""withdrawalAddresses"", + ""outputs"": [ + { + ""internalType"": ""string"", + ""name"": """", + ""type"": ""string"" + } + ], + ""stateMutability"": ""view"", + ""type"": ""function"" + } + ]"; + } +}