github.com/Consensys/quorum@v21.1.0+incompatible/core/private_state_test.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"github.com/ethereum/go-ethereum/common"
     9  	"github.com/ethereum/go-ethereum/crypto"
    10  )
    11  
    12  // callmsg is the message type used for call transactions in the private state test
    13  type callmsg struct {
    14  	addr     common.Address
    15  	to       *common.Address
    16  	gas      uint64
    17  	gasPrice *big.Int
    18  	value    *big.Int
    19  	data     []byte
    20  }
    21  
    22  // accessor boilerplate to implement core.Message
    23  func (m callmsg) From() common.Address         { return m.addr }
    24  func (m callmsg) FromFrontier() common.Address { return m.addr }
    25  func (m callmsg) Nonce() uint64                { return 0 }
    26  func (m callmsg) To() *common.Address          { return m.to }
    27  func (m callmsg) GasPrice() *big.Int           { return m.gasPrice }
    28  func (m callmsg) Gas() uint64                  { return m.gas }
    29  func (m callmsg) Value() *big.Int              { return m.value }
    30  func (m callmsg) Data() []byte                 { return m.data }
    31  func (m callmsg) CheckNonce() bool             { return true }
    32  
    33  func ExampleMakeCallHelper() {
    34  	var (
    35  		// setup new pair of keys for the calls
    36  		key, _ = crypto.GenerateKey()
    37  		// create a new helper
    38  		helper = MakeCallHelper()
    39  	)
    40  	// Private contract address
    41  	prvContractAddr := common.Address{1}
    42  	// Initialise custom code for private contract
    43  	helper.PrivateState.SetCode(prvContractAddr, common.Hex2Bytes("600a60005500"))
    44  	// Public contract address
    45  	pubContractAddr := common.Address{2}
    46  	// Initialise custom code for public contract
    47  	helper.PublicState.SetCode(pubContractAddr, common.Hex2Bytes("601460005500"))
    48  
    49  	// Make a call to the private contract
    50  	err := helper.MakeCall(true, key, prvContractAddr, nil)
    51  	if err != nil {
    52  		fmt.Println(err)
    53  	}
    54  	// Make a call to the public contract
    55  	err = helper.MakeCall(false, key, pubContractAddr, nil)
    56  	if err != nil {
    57  		fmt.Println(err)
    58  	}
    59  
    60  	// Output:
    61  	// Private: 10
    62  	// Public: 20
    63  	fmt.Println("Private:", helper.PrivateState.GetState(prvContractAddr, common.Hash{}).Big())
    64  	fmt.Println("Public:", helper.PublicState.GetState(pubContractAddr, common.Hash{}).Big())
    65  }
    66  
    67  // 600a600055600060006001a1
    68  // 60 0a, 60 00, 55,  60 00, 60 00, 60 01,  a1
    69  // [1] (0x60) PUSH1 0x0a (store value)
    70  // [3] (0x60) PUSH1 0x00 (store addr)
    71  // [4] (0x55) SSTORE  (Store (k-00,v-a))
    72  
    73  // [6] (0x60) PUSH1 0x00
    74  // [8] (0x60) PUSH1 0x00
    75  // [10](0x60) PUSH1 0x01
    76  // [11](0xa1) LOG1 offset(0x01), len(0x00), topic(0x00)
    77  //
    78  // Store then log
    79  func TestPrivateTransaction(t *testing.T) {
    80  	var (
    81  		key, _       = crypto.GenerateKey()
    82  		helper       = MakeCallHelper()
    83  		privateState = helper.PrivateState
    84  		publicState  = helper.PublicState
    85  	)
    86  
    87  	prvContractAddr := common.Address{1}
    88  	pubContractAddr := common.Address{2}
    89  	// SSTORE (K,V) SSTORE(0, 10): 600a600055
    90  	// +
    91  	// LOG1 OFFSET LEN TOPIC,  LOG1 (a1) 01, 00, 00: 600060006001a1
    92  	privateState.SetCode(prvContractAddr, common.Hex2Bytes("600a600055600060006001a1"))
    93  	// SSTORE (K,V) SSTORE(0, 14): 6014600055
    94  	publicState.SetCode(pubContractAddr, common.Hex2Bytes("6014600055"))
    95  
    96  	if publicState.Exist(prvContractAddr) {
    97  		t.Error("didn't expect private contract address to exist on public state")
    98  	}
    99  
   100  	// Private transaction 1
   101  	err := helper.MakeCall(true, key, prvContractAddr, nil)
   102  
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	stateEntry := privateState.GetState(prvContractAddr, common.Hash{}).Big()
   107  	if stateEntry.Cmp(big.NewInt(10)) != 0 {
   108  		t.Error("expected state to have 10, got", stateEntry)
   109  	}
   110  	if len(privateState.Logs()) != 1 {
   111  		t.Error("expected private state to have 1 log, got", len(privateState.Logs()))
   112  	}
   113  	if len(publicState.Logs()) != 0 {
   114  		t.Error("expected public state to have 0 logs, got", len(publicState.Logs()))
   115  	}
   116  	if publicState.Exist(prvContractAddr) {
   117  		t.Error("didn't expect private contract address to exist on public state")
   118  	}
   119  	if !privateState.Exist(prvContractAddr) {
   120  		t.Error("expected private contract address to exist on private state")
   121  	}
   122  
   123  	// Public transaction 1
   124  	err = helper.MakeCall(false, key, pubContractAddr, nil)
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	stateEntry = publicState.GetState(pubContractAddr, common.Hash{}).Big()
   129  	if stateEntry.Cmp(big.NewInt(20)) != 0 {
   130  		t.Error("expected state to have 20, got", stateEntry)
   131  	}
   132  
   133  	// Private transaction 2
   134  	err = helper.MakeCall(true, key, prvContractAddr, nil)
   135  	stateEntry = privateState.GetState(prvContractAddr, common.Hash{}).Big()
   136  	if stateEntry.Cmp(big.NewInt(10)) != 0 {
   137  		t.Error("expected state to have 10, got", stateEntry)
   138  	}
   139  
   140  	if publicState.Exist(prvContractAddr) {
   141  		t.Error("didn't expect private contract address to exist on public state")
   142  	}
   143  	if privateState.Exist(pubContractAddr) {
   144  		t.Error("didn't expect public contract address to exist on private state")
   145  	}
   146  }