diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/block/main.go | 151 | ||||
-rw-r--r-- | examples/chain/main.go | 6 | ||||
-rw-r--r-- | examples/counter/main.go | 5 | ||||
-rw-r--r-- | examples/fc/main.go | 16 | ||||
-rw-r--r-- | examples/multicoin/main.go | 219 | ||||
-rw-r--r-- | examples/multicoin/mc_test.sol | 27 | ||||
-rw-r--r-- | examples/payments/main.go | 4 |
7 files changed, 405 insertions, 23 deletions
diff --git a/examples/block/main.go b/examples/block/main.go new file mode 100644 index 0000000..45d7586 --- /dev/null +++ b/examples/block/main.go @@ -0,0 +1,151 @@ +package main + +import ( + "bytes" + "fmt" + "github.com/ava-labs/coreth" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/eth" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/go-ethereum/common" + "github.com/ava-labs/go-ethereum/common/hexutil" + "github.com/ava-labs/go-ethereum/crypto" + "github.com/ava-labs/go-ethereum/rlp" + "math/big" +) + +func checkError(err error) { + if err != nil { + panic(err) + } +} + +func main() { + // configure the chain + config := eth.DefaultConfig + config.ManualCanonical = true + chainConfig := ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: nil, + Ethash: nil, + } + + // configure the genesis block + genBalance := big.NewInt(100000000000000000) + hk, _ := crypto.HexToECDSA( + "abd71b35d559563fea757f0f5edbde286fb8c043105b15abb7cd57189306d7d1") + genKey := coreth.NewKeyFromECDSA(hk) + + config.Genesis = &core.Genesis{ + Config: chainConfig, + Nonce: 0, + Number: 0, + ExtraData: hexutil.MustDecode("0x00"), + GasLimit: 100000000, + Difficulty: big.NewInt(0), + Alloc: core.GenesisAlloc{genKey.Address: {Balance: genBalance}}, + } + + // grab the control of block generation and disable auto uncle + config.Miner.ManualMining = true + config.Miner.DisableUncle = true + + chain := coreth.NewETHChain(&config, nil, nil, nil) + buff := new(bytes.Buffer) + blk := chain.GetGenesisBlock() + err := blk.EncodeRLPEth(buff) + buff.WriteString("somesuffix") + checkError(err) + var blk2 *types.Block + blk2 = new(types.Block) + fmt.Println(buff.Len()) + fmt.Println(common.ToHex(buff.Bytes())) + + err = rlp.Decode(buff, blk2) + fmt.Println(buff.Len()) + checkError(err) + buff.Reset() + err = blk2.EncodeRLPEth(buff) + checkError(err) + fmt.Println(buff.Len()) + fmt.Println(common.ToHex(buff.Bytes())) + + err = rlp.Decode(buff, blk2) + fmt.Println(buff.Len()) + checkError(err) + buff.Reset() + err = blk2.EncodeRLP(buff) + checkError(err) + buff.WriteString("somesuffix") + fmt.Println(buff.Len()) + fmt.Println(common.ToHex(buff.Bytes())) + + err = rlp.Decode(buff, blk2) + fmt.Println(buff.Len()) + checkError(err) + buff.Reset() + err = blk2.EncodeRLP(buff) + checkError(err) + fmt.Println(buff.Len()) + fmt.Println(common.ToHex(buff.Bytes())) + + err = rlp.Decode(buff, blk2) + fmt.Println(buff.Len()) + checkError(err) + buff.Reset() + extra, err := rlp.EncodeToBytes("test extra data") + blk2.SetExtraData(extra) + err = blk2.EncodeRLPTest(buff, 0xffffffff) + checkError(err) + buff.WriteString("somesuffix") + fmt.Println(buff.Len()) + fmt.Println(blk2.Hash().Hex()) + + err = rlp.Decode(buff, blk2) + checkError(err) + fmt.Println(buff.Len(), (string)(blk2.ExtraData()), blk2.Hash().Hex()) + decoded1 := new(string) + err = rlp.DecodeBytes(blk2.ExtraData(), decoded1) + checkError(err) + fmt.Println(buff.Len(), decoded1) + fmt.Println(common.ToHex(buff.Bytes())) + + buff.Reset() + type NestedData struct { + A uint16 + B uint16 + S string + } + type MyData struct { + X uint32 + Y uint32 + Msg string + Inner NestedData + } + extra, err = rlp.EncodeToBytes(MyData{ + X: 4200, Y: 4300, Msg: "hello", Inner: NestedData{A: 1, B: 2, S: "world"}, + }) + checkError(err) + blk2.SetExtraData(extra) + err = blk2.EncodeRLPTest(buff, 0xfffffffe) + checkError(err) + fmt.Println(blk2.Hash().Hex()) + err = rlp.Decode(buff, blk2) + checkError(err) + decoded2 := new(MyData) + err = rlp.DecodeBytes(blk2.ExtraData(), decoded2) + checkError(err) + fmt.Println(buff.Len(), decoded2, blk2.Hash().Hex()) + buff.Reset() +} diff --git a/examples/chain/main.go b/examples/chain/main.go index cd9a8f9..26fc5ce 100644 --- a/examples/chain/main.go +++ b/examples/chain/main.go @@ -4,13 +4,13 @@ import ( "crypto/rand" "fmt" "github.com/ava-labs/coreth" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" + "github.com/ava-labs/coreth/params" "github.com/ava-labs/go-ethereum/common" "github.com/ava-labs/go-ethereum/common/hexutil" - "github.com/ava-labs/go-ethereum/core" - "github.com/ava-labs/go-ethereum/core/types" "github.com/ava-labs/go-ethereum/log" - "github.com/ava-labs/go-ethereum/params" "github.com/ava-labs/go-ethereum/rlp" "math/big" "sync" diff --git a/examples/counter/main.go b/examples/counter/main.go index 86e839a..85aa9d1 100644 --- a/examples/counter/main.go +++ b/examples/counter/main.go @@ -7,13 +7,13 @@ import ( "fmt" "github.com/ava-labs/coreth" "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" + "github.com/ava-labs/coreth/params" "github.com/ava-labs/go-ethereum/common" "github.com/ava-labs/go-ethereum/common/compiler" - "github.com/ava-labs/go-ethereum/core/types" "github.com/ava-labs/go-ethereum/crypto" "github.com/ava-labs/go-ethereum/log" - "github.com/ava-labs/go-ethereum/params" "go/build" "math/big" "os" @@ -57,6 +57,7 @@ func main() { b := `{"config":{"chainId":1,"homesteadBlock":0,"daoForkBlock":0,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"0x5f5e100","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"751a0b96e1042bee789452ecb20253fba40dbe85":{"balance":"0x16345785d8a0000"}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}` k := "0xabd71b35d559563fea757f0f5edbde286fb8c043105b15abb7cd57189306d7d1" err := json.Unmarshal([]byte(b), g) + checkError(err) config.Genesis = g hk, _ := crypto.HexToECDSA(k[2:]) genKey = coreth.NewKeyFromECDSA(hk) diff --git a/examples/fc/main.go b/examples/fc/main.go deleted file mode 100644 index f4bf65d..0000000 --- a/examples/fc/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "github.com/ava-labs/coreth/cmd/geth" - "os" -) - -func checkError(err error) { - if err != nil { - panic(err) - } -} - -func main() { - geth.App.Run(os.Args) -} diff --git a/examples/multicoin/main.go b/examples/multicoin/main.go new file mode 100644 index 0000000..3b221b1 --- /dev/null +++ b/examples/multicoin/main.go @@ -0,0 +1,219 @@ +package main + +import ( + "crypto/rand" + "encoding/json" + "fmt" + "github.com/ava-labs/coreth" + "github.com/ava-labs/coreth/accounts/abi" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/core/vm" + "github.com/ava-labs/coreth/eth" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/go-ethereum/common" + "github.com/ava-labs/go-ethereum/common/compiler" + "github.com/ava-labs/go-ethereum/crypto" + "github.com/ava-labs/go-ethereum/log" + "go/build" + "math/big" + "os" + "os/signal" + "path/filepath" + "strings" + "syscall" + "time" +) + +func checkError(err error) { + if err != nil { + panic(err) + } +} + +func main() { + // configure the chain + config := eth.DefaultConfig + config.ManualCanonical = true + chainConfig := ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: nil, + Ethash: nil, + } + + // configure the genesis block + genesisJSON := `{"config":{"chainId":1,"homesteadBlock":0,"daoForkBlock":0,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"0x5f5e100","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"751a0b96e1042bee789452ecb20253fba40dbe85":{"balance":"0x1000000000000000", "mcbalance": {"0x0000000000000000000000000000000000000000000000000000000000000000": 1000000000000000000}}, "0100000000000000000000000000000000000000": {"code": "0x730000000000000000000000000000000000000000301460806040526004361061004b5760003560e01c80631e01043914610050578063abb24ba014610092578063b6510bb3146100a9575b600080fd5b61007c6004803603602081101561006657600080fd5b8101908080359060200190929190505050610118565b6040518082815260200191505060405180910390f35b81801561009e57600080fd5b506100a761013b565b005b8180156100b557600080fd5b50610116600480360360808110156100cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061013e565b005b60003073ffffffffffffffffffffffffffffffffffffffff1682905d9050919050565b5c565b8373ffffffffffffffffffffffffffffffffffffffff1681836108fc8690811502906040516000604051808303818888878c8af69550505050505015801561018a573d6000803e3d6000fd5b505050505056fea2646970667358221220ed2100d6623a884d196eceefabe5e03da4309a2562bb25262f3874f1acb31cd764736f6c634300060a0033", "balance": "0x0", "mcbalance": {}}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}` + mcAbiJSON := `[{"inputs":[],"name":"enableMultiCoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"coinid","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"coinid","type":"uint256"},{"internalType":"uint256","name":"amount2","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"}]` + genesisKey := "0xabd71b35d559563fea757f0f5edbde286fb8c043105b15abb7cd57189306d7d1" + + bobKey, _ := coreth.NewKey(rand.Reader) + genesisBlock := new(core.Genesis) + err := json.Unmarshal([]byte(genesisJSON), genesisBlock) + checkError(err) + hk, _ := crypto.HexToECDSA(genesisKey[2:]) + genKey := coreth.NewKeyFromECDSA(hk) + + config.Genesis = genesisBlock + // grab the control of block generation and disable auto uncle + config.Miner.ManualMining = true + config.Miner.ManualUncle = true + + // compile the smart contract + gopath := os.Getenv("GOPATH") + if gopath == "" { + gopath = build.Default.GOPATH + } + counterSrc, err := filepath.Abs(gopath + "/src/github.com/ava-labs/coreth/examples/multicoin/mc_test.sol") + checkError(err) + contracts, err := compiler.CompileSolidity("", counterSrc) + checkError(err) + contract, _ := contracts[fmt.Sprintf("%s:%s", counterSrc, "MCTest")] + + // info required to generate a transaction + chainID := chainConfig.ChainID + nonce := uint64(0) + gasLimit := 10000000 + gasPrice := big.NewInt(1000000000) + + blockCount := 0 + chain := coreth.NewETHChain(&config, nil, nil, nil) + newTxPoolHeadChan := make(chan core.NewTxPoolHeadEvent, 1) + log.Info(chain.GetGenesisBlock().Hash().Hex()) + + mcAbi, err := abi.JSON(strings.NewReader(mcAbiJSON)) + checkError(err) + enableCode, err := mcAbi.Pack("enableMultiCoin") + checkError(err) + + abiStr, err := json.Marshal(contract.Info.AbiDefinition) + contractAbi, err := abi.JSON(strings.NewReader(string(abiStr))) + checkError(err) + + var contractAddr common.Address + postGen := func(block *types.Block) bool { + if blockCount == 15 { + coin0 := common.HexToHash("0x0") + state, err := chain.CurrentState() + checkError(err) + log.Info(fmt.Sprintf("genesis balance = %s", state.GetBalance(genKey.Address))) + log.Info(fmt.Sprintf("genesis mcbalance(0) = %s", state.GetBalanceMultiCoin(genKey.Address, coin0))) + log.Info(fmt.Sprintf("bob's balance = %s", state.GetBalance(bobKey.Address))) + log.Info(fmt.Sprintf("bob's mcbalance(0) = %s", state.GetBalanceMultiCoin(bobKey.Address, coin0))) + log.Info(fmt.Sprintf("contract mcbalance(0) = %s", state.GetBalanceMultiCoin(contractAddr, coin0))) + log.Info(fmt.Sprintf("state = %s", state.Dump(true, false, true))) + return true + } + if blockCount == 1 { + receipts := chain.GetReceiptsByHash(block.Hash()) + if len(receipts) != 1 { + panic(fmt.Sprintf("# receipts is %d != 1", len(receipts))) + } + contractAddr = receipts[0].ContractAddress + log.Info(fmt.Sprintf("contract addr = %s", contractAddr.String())) + + go func() { + // give Bob some initial balance + tx := types.NewTransaction(nonce, bobKey.Address, big.NewInt(300000000000000000), uint64(gasLimit), gasPrice, nil) + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + nonce++ + time.Sleep(20 * time.Millisecond) + + // enable MC for Bob + tx = types.NewTransaction(0, vm.BuiltinAddr, big.NewInt(0), uint64(gasLimit), gasPrice, enableCode) + signedTx, err = types.SignTx(tx, types.NewEIP155Signer(chainID), bobKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + + time.Sleep(20 * time.Millisecond) + + bobTransferInput, err := mcAbi.Pack("transfer", bobKey.Address, big.NewInt(0), big.NewInt(0), big.NewInt(100000000000000000)) + checkError(err) + contractTransferInput, err := mcAbi.Pack("transfer", contractAddr, big.NewInt(0), big.NewInt(0), big.NewInt(100000000000000000)) + checkError(err) + + for i := 0; i < 5; i++ { + // transfer some coin0 balance to Bob + tx := types.NewTransaction(nonce, vm.BuiltinAddr, big.NewInt(0), uint64(gasLimit), gasPrice, bobTransferInput) + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + nonce++ + + // transfer some coin0 balance to the contract + tx = types.NewTransaction(nonce, vm.BuiltinAddr, big.NewInt(0), uint64(gasLimit), gasPrice, contractTransferInput) + signedTx, err = types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + nonce++ + } + + // test contract methods + + input, err := contractAbi.Pack("withdraw", big.NewInt(0), big.NewInt(0), big.NewInt(10000000000000000)) + tx = types.NewTransaction(nonce, contractAddr, big.NewInt(0), uint64(gasLimit), gasPrice, input) + signedTx, err = types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + nonce++ + + input, err = contractAbi.Pack("updateBalance", big.NewInt(0)) + tx = types.NewTransaction(nonce, contractAddr, big.NewInt(0), uint64(gasLimit), gasPrice, input) + signedTx, err = types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + nonce++ + }() + } + return false + } + chain.SetOnHeaderNew(func(header *types.Header) { + hid := make([]byte, 32) + _, err := rand.Read(hid) + if err != nil { + panic("cannot generate hid") + } + header.Extra = append(header.Extra, hid...) + }) + chain.SetOnSealFinish(func(block *types.Block) error { + blockCount++ + if postGen(block) { + return nil + } + go func() { + <-newTxPoolHeadChan + time.Sleep(10 * time.Millisecond) + chain.GenBlock() + }() + return nil + }) + + // start the chain + chain.GetTxPool().SubscribeNewHeadEvent(newTxPoolHeadChan) + chain.Start() + code := common.Hex2Bytes(contract.Code[2:]) + + tx := types.NewContractCreation(nonce, big.NewInt(0), uint64(gasLimit), gasPrice, code) + signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), genKey.PrivateKey) + checkError(err) + chain.AddRemoteTxs([]*types.Transaction{signedTx}) + nonce++ + chain.GenBlock() + + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + signal.Notify(c, os.Interrupt, syscall.SIGINT) + <-c + chain.Stop() +} diff --git a/examples/multicoin/mc_test.sol b/examples/multicoin/mc_test.sol new file mode 100644 index 0000000..ec07ee6 --- /dev/null +++ b/examples/multicoin/mc_test.sol @@ -0,0 +1,27 @@ +pragma solidity >=0.6.0; + +contract MCTest { + address constant MultiCoin = 0x0100000000000000000000000000000000000000; + uint256 balance; + constructor() public { + // enable multi-coin functionality (it is disabled by default) + (bool success,) = MultiCoin.call(abi.encodeWithSignature("enableMultiCoin()")); + require(success); + } + + function updateBalance(uint256 coinid) public { + (bool success, bytes memory data) = MultiCoin.call(abi.encodeWithSignature("getBalance(uint256)", coinid)); + require(success); + balance = abi.decode(data, (uint256)); + } + + function withdraw(uint256 amount, uint256 coinid, uint256 amount2) public { + (bool success,) = MultiCoin.call( + abi.encodeWithSignature("transfer(address,uint256,uint256,uint256)", + msg.sender, amount, coinid, amount2)); + + require(success); + } + + receive() external payable {} +} diff --git a/examples/payments/main.go b/examples/payments/main.go index 5076737..40a90c2 100644 --- a/examples/payments/main.go +++ b/examples/payments/main.go @@ -5,12 +5,12 @@ import ( "fmt" "github.com/ava-labs/coreth" "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" + "github.com/ava-labs/coreth/params" "github.com/ava-labs/go-ethereum/common" "github.com/ava-labs/go-ethereum/common/hexutil" - "github.com/ava-labs/go-ethereum/core/types" "github.com/ava-labs/go-ethereum/log" - "github.com/ava-labs/go-ethereum/params" "math/big" ) |