aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/block/main.go151
-rw-r--r--examples/chain/main.go6
-rw-r--r--examples/counter/main.go5
-rw-r--r--examples/fc/main.go16
-rw-r--r--examples/multicoin/main.go219
-rw-r--r--examples/multicoin/mc_test.sol27
-rw-r--r--examples/payments/main.go4
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 := &params.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 := &params.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"
)