Created
December 1, 2018 15:27
-
-
Save hugoroussel/eac67ab937d02c90fc237c6e6d15dfbc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package byzcoin | |
| import ( | |
| "github.com/ethereum/go-ethereum/accounts/abi" | |
| "math/big" | |
| "strings" | |
| "testing" | |
| "time" | |
| "github.com/dedis/onet/log" | |
| "github.com/ethereum/go-ethereum/common" | |
| "github.com/dedis/protobuf" | |
| "github.com/stretchr/testify/require" | |
| "github.com/dedis/cothority" | |
| "github.com/dedis/cothority/byzcoin" | |
| "github.com/dedis/cothority/darc" | |
| "github.com/dedis/onet" | |
| ) | |
| func TestEVMContract_Spawn(t *testing.T) { | |
| log.LLvl1("test: instance creation") | |
| // Create a new ledger and prepare for proper closing | |
| bct := newBCTest(t) | |
| defer bct.Close() | |
| // Create a new empty instance | |
| args := byzcoin.Arguments{} | |
| // And send it to the ledger. | |
| instID := bct.createInstance(t, args) | |
| // Wait for the proof to be available. | |
| pr, err := bct.cl.WaitProof(instID, bct.gMsg.BlockInterval, nil) | |
| require.Nil(t, err) | |
| // Make sure the proof is a matching proof and not a proof of absence. | |
| require.True(t, pr.InclusionProof.Match()) | |
| // Get the raw values of the proof. | |
| values, err := pr.InclusionProof.RawValues() | |
| require.Nil(t, err) | |
| // And decode the buffer to a ContractStruct. | |
| cs := KeyValueData{} | |
| err = protobuf.Decode(values[0], &cs) | |
| require.Nil(t, err) | |
| } | |
| func TestEVMContract_Invoke_Credit(t *testing.T) { | |
| log.LLvl1("test: crediting an account") | |
| bct := newBCTest(t) | |
| defer bct.Close() | |
| address := "0x2afd357E96a3aCbcd01615681C1D7e3398d5fb61" | |
| addressB := []byte(address) | |
| value := []byte("1000") | |
| args := byzcoin.Arguments{ | |
| { | |
| Name: "address", | |
| Value: addressB, | |
| }, | |
| { | |
| Name: "value", | |
| Value: value, | |
| }, | |
| } | |
| instID := bct.createInstance(t, args) | |
| // Wait for the proof to be available. | |
| _, err := bct.cl.WaitProof(instID, bct.gMsg.BlockInterval, nil) | |
| require.Nil(t, err) | |
| bct.creditAccountInstance(t, instID, args) | |
| require.Nil(t, err) | |
| log.LLvl1("hello") | |
| } | |
| func TestEVMContract_Invoke_Call(t *testing.T) { | |
| log.LLvl1("test: call a contract") | |
| bct := newBCTest(t) | |
| //defer bct.Close() | |
| args := byzcoin.Arguments{} | |
| instID := bct.createInstance(t, args) | |
| // Wait for the proof to be available. | |
| pr1, err := bct.cl.WaitProof(instID, bct.gMsg.BlockInterval, nil) | |
| _, _, err = pr1.KeyValue() | |
| require.Nil(t, err) | |
| args, err = getAbiCallForCreate() | |
| require.Nil(t, err) | |
| bct.methodCallInstance(t, instID, args) | |
| require.Nil(t, err) | |
| /* | |
| args = getArgsForTransfer() | |
| bct.methodCallInstance(t, instID, args) | |
| require.Nil(t, err)*/ | |
| } | |
| func TestEVMContract_Apply_Transaction(t *testing.T){ | |
| log.LLvl1("Testing applying tx") | |
| sendTransactionHelper(&common.Address{0x01}) | |
| } | |
| func getAbiCallForCreate() (ba byzcoin.Arguments , err error){ | |
| abiBuf := `[{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"send","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"toGiveTo","type":"address"}],"name":"create","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]` | |
| methodName := "create" | |
| contractAddress := []byte("0xBd770416a3345F91E4B34576cb804a576fa48EB1") | |
| publicKey := common.HexToAddress("0x1111111111111111111111111111111111111111") | |
| initialSupply := int64(100) | |
| ABI, err := abi.JSON(strings.NewReader(string(abiBuf))) | |
| if err != nil { | |
| return nil, err | |
| } | |
| abiCall, err := ABI.Pack(methodName, big.NewInt(initialSupply), publicKey) | |
| if err != nil { | |
| return nil, err | |
| } | |
| ba = byzcoin.Arguments{ | |
| { | |
| Name: "contractAddress", | |
| Value: contractAddress, | |
| }, | |
| { | |
| Name: "abiCall", | |
| Value: abiCall, | |
| }, | |
| } | |
| return | |
| } | |
| func getArgsForTransfer() byzcoin.Arguments{ | |
| abi := []byte(`[{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"send","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"toGiveTo","type":"address"}],"name":"create","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`) | |
| methodName := []byte("transfer") | |
| contractAddress := []byte("0xBd770416a3345F91E4B34576cb804a576fa48EB1") | |
| aPublicKey := []byte("0x1111111111111111111111111111111111111111") | |
| bPublicKey := []byte("0x2222222222222222222222222222222222222222") | |
| args := byzcoin.Arguments{ | |
| { | |
| Name: "abi", | |
| Value: abi, | |
| }, | |
| { | |
| Name: "method", | |
| Value: methodName, | |
| }, | |
| { | |
| Name: "contractAddress", | |
| Value: contractAddress, | |
| }, | |
| { | |
| Name: "from", | |
| Value: aPublicKey, | |
| }, | |
| { | |
| Name: "to", | |
| Value: bPublicKey, | |
| }, | |
| } | |
| return args | |
| } | |
| // bcTest is used here to provide some simple test structure for different | |
| // tests. | |
| type bcTest struct { | |
| local *onet.LocalTest | |
| signer darc.Signer | |
| servers []*onet.Server | |
| roster *onet.Roster | |
| cl *byzcoin.Client | |
| gMsg *byzcoin.CreateGenesisBlock | |
| gDarc *darc.Darc | |
| } | |
| func newBCTest(t *testing.T) (out *bcTest) { | |
| out = &bcTest{} | |
| // First create a local test environment with three nodes. | |
| out.local = onet.NewTCPTest(cothority.Suite) | |
| out.signer = darc.NewSignerEd25519(nil, nil) | |
| out.servers, out.roster, _ = out.local.GenTree(3, true) | |
| // Then create a new ledger with the genesis darc having the right | |
| // to create and update keyValue contracts. | |
| var err error | |
| out.gMsg, err = byzcoin.DefaultGenesisMsg(byzcoin.CurrentVersion, out.roster, | |
| []string{"spawn:keyValue", "spawn:darc", "spawn:bvm", "invoke:credit", "invoke:transaction"}, out.signer.Identity()) | |
| require.Nil(t, err) | |
| out.gDarc = &out.gMsg.GenesisDarc | |
| // This BlockInterval is good for testing, but in real world applications this | |
| // should be more like 5 seconds. | |
| out.gMsg.BlockInterval = time.Second / 2 | |
| out.cl, _, err = byzcoin.NewLedger(out.gMsg, false) | |
| require.Nil(t, err) | |
| return out | |
| } | |
| func (bct *bcTest) Close() { | |
| bct.local.CloseAll() | |
| } | |
| func (bct *bcTest) createInstance(t *testing.T, args byzcoin.Arguments) byzcoin.InstanceID { | |
| ctx := byzcoin.ClientTransaction{ | |
| Instructions: []byzcoin.Instruction{{ | |
| InstanceID: byzcoin.NewInstanceID(bct.gDarc.GetBaseID()), | |
| Nonce: byzcoin.Nonce{}, | |
| Index: 0, | |
| Length: 1, | |
| Spawn: &byzcoin.Spawn{ | |
| ContractID: ContractBvmID, | |
| Args: args, | |
| }, | |
| }}, | |
| } | |
| // And we need to sign the instruction with the signer that has his | |
| // public key stored in the darc. | |
| require.Nil(t, ctx.Instructions[0].SignBy(bct.gDarc.GetBaseID(), bct.signer)) | |
| // Sending this transaction to ByzCoin does not directly include it in the | |
| // global state - first we must wait for the new block to be created. | |
| var err error | |
| _, err = bct.cl.AddTransactionAndWait(ctx, 20) | |
| require.Nil(t, err) | |
| return ctx.Instructions[0].DeriveID("") | |
| } | |
| func (bct *bcTest) creditAccountInstance(t *testing.T, instID byzcoin.InstanceID, args byzcoin.Arguments) { | |
| ctx := byzcoin.ClientTransaction{ | |
| Instructions: []byzcoin.Instruction{{ | |
| InstanceID: instID, | |
| Nonce: byzcoin.Nonce{}, | |
| Index: 0, | |
| Length: 1, | |
| Invoke: &byzcoin.Invoke{ | |
| Command: "credit", | |
| Args: args, | |
| }, | |
| }}, | |
| } | |
| log.LLvl1(" credit byzcoin transaction ") | |
| // And we need to sign the instruction with the signer that has his | |
| // public key stored in the darc. | |
| require.Nil(t, ctx.Instructions[0].SignBy(bct.gDarc.GetBaseID(), bct.signer)) | |
| // Sending this transaction to ByzCoin does not directly include it in the | |
| // global state - first we must wait for the new block to be created. | |
| var err error | |
| _, err = bct.cl.AddTransactionAndWait(ctx, 20) | |
| require.Nil(t, err) | |
| } | |
| func (bct *bcTest) methodCallInstance(t *testing.T, instID byzcoin.InstanceID, args byzcoin.Arguments) { | |
| ctx := byzcoin.ClientTransaction{ | |
| Instructions: []byzcoin.Instruction{{ | |
| InstanceID: instID, | |
| Nonce: byzcoin.Nonce{}, | |
| Index: 0, | |
| Length: 1, | |
| Invoke: &byzcoin.Invoke{ | |
| Command: "call", | |
| Args: args, | |
| }, | |
| }}, | |
| } | |
| // And we need to sign the instruction with the signer that has his | |
| // public key stored in the darc. | |
| require.Nil(t, ctx.Instructions[0].SignBy(bct.gDarc.GetBaseID(), bct.signer)) | |
| // Sending this transaction to ByzCoin does not directly include it in the | |
| // global state - first we must wait for the new block to be created. | |
| var err error | |
| _, err = bct.cl.AddTransactionAndWait(ctx, 20) | |
| require.Nil(t, err) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment