在网上找了一些关于C#开发以太仿的资料,大概了解了以太仿常用名词,后续可能需要根据资料查看开源的源码进一步熟悉一下。
一、准备合约
这里准备了一个EzToken.sol合约,目前还不会solidity,所以随便在网上找了一个,由于使用的是solidity的版本是0.5.6的版本,所以需要在string memory _tokenName,中加memory,否则会报错。
pragma solidity >=0.4.21 <0.6.0; contract EzToken { uint256 public totalSupply; mapping (address => uint256) public balances; mapping (address => mapping (address => uint256)) public allowed; string public name; uint8 public decimals; string public symbol; event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); constructor( uint256 _initialAmount, string memory _tokenName, uint8 _decimalUnits, string memory _tokenSymbol ) public { balances[msg.sender] = _initialAmount; totalSupply = _initialAmount; name = _tokenName; decimals = _decimalUnits; symbol = _tokenSymbol; } function transfer(address _to, uint256 _value) public returns (bool success) { require(balances[msg.sender] >= _value); balances[msg.sender] -= _value; balances[_to] += _value; emit Transfer(msg.sender, _to, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { uint256 allowance = allowed[_from][msg.sender]; require(balances[_from] >= _value && allowance >= _value); balances[_to] += _value; balances[_from] -= _value; allowed[_from][msg.sender] -= _value; emit Transfer(_from, _to, _value); return true; } function balanceOf(address _owner) public view returns (uint256 balance) { return balances[_owner]; } function approve(address _spender, uint256 _value) public returns (bool success) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function allowance(address _owner, address _spender) public view returns (uint256 remaining) { return allowed[_owner][_spender]; } }
二、编译合约
编译合约我这边下载了window版本的solidity编译器https://github.com/ethereum/solidity/releases,这里我下载的是window的0.5.6版本。
然后在solidity-windows目录下cmd命令输入下面命令,之后会编译出一个abi文件、一个bin文件,关于solidity后续还需要进一步学习。
solc ../EzToken.sol --bin --abi --optimize --overwrite -o ../
三、部署
部署合约也是一个交易,只是与普通的交易相比,部署交易 需要把合约的字节码和编码后构造函数参数放在请求报文参数中的data字段里, 然后通过eth_sendTransaction或eth_sendRawTransaction调用提交给节点。这里发行了CYW的代币。
using Nethereum.Hex.HexConvertors.Extensions; using Nethereum.Hex.HexTypes; using Nethereum.RPC.Eth.DTOs; using Nethereum.Web3; using System; using System.IO; using System.Numerics; using System.Threading; using System.Threading.Tasks; using Nethereum.ABI.FunctionEncoding; using Nethereum.ABI.Model; namespace DeployContractTheory { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); Run().Wait(); Console.ReadLine(); } public static async Task Run() { string abi = File.ReadAllText("EzToken.abi"); string bin = File.ReadAllText("EzToken.bin"); ParametersEncoder encoder = new ParametersEncoder(); Parameter[] parameters = new Parameter[] { new Parameter("uint256"), new Parameter("string"), new Parameter("uint8"), new Parameter("string") }; BigInteger initialAmount = new BigInteger(1000000000); string tokenName = "CYW"; BigInteger decimalUnits = new BigInteger(0); string tokenSymbol = "CuiYW"; byte[] encodedParams = encoder.EncodeParameters(parameters, initialAmount, tokenName, decimalUnits, tokenSymbol); string data = "0x" + bin + encodedParams.ToHex(false); Web3 web3 = new Web3("http://localhost:7545"); string[] accounts = await web3.Eth.Accounts.SendRequestAsync(); TransactionInput txinput = new TransactionInput { From = accounts[0], Data = data, Gas = new HexBigInteger(1000000), GasPrice = new HexBigInteger(20000000000) }; string txhash = await web3.TransactionManager.SendTransactionAsync(txinput); TransactionReceipt receipt = null; while (true) { receipt = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txhash); if (receipt != null) break; Thread.Sleep(1000); } Console.WriteLine("contract deployed at => " + receipt.ContractAddress); } } }