state_prefetcher_private_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. package core
  2. import (
  3. "crypto/ecdsa"
  4. "encoding/base64"
  5. "math/big"
  6. "os"
  7. "testing"
  8. "github.com/ethereum/go-ethereum/core/mps"
  9. "github.com/ethereum/go-ethereum/common"
  10. "github.com/ethereum/go-ethereum/consensus/ethash"
  11. "github.com/ethereum/go-ethereum/core/rawdb"
  12. "github.com/ethereum/go-ethereum/core/state"
  13. "github.com/ethereum/go-ethereum/core/types"
  14. "github.com/ethereum/go-ethereum/core/vm"
  15. "github.com/ethereum/go-ethereum/crypto"
  16. "github.com/ethereum/go-ethereum/params"
  17. "github.com/ethereum/go-ethereum/private"
  18. privateEngine "github.com/ethereum/go-ethereum/private/engine"
  19. "github.com/golang/mock/gomock"
  20. "github.com/stretchr/testify/assert"
  21. )
  22. var (
  23. contractDeployed = &contract{
  24. name: "contractDeployed",
  25. abi: mustParse(contractDeployedDefinition),
  26. bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806105a88339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610550806100586000396000f3fe608060405260043610610051576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100565780636d4ce63c146100a5578063d7139463146100d0575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b810190808035906020019092919050505061010b565b6040518082815260200191505060405180910390f35b3480156100b157600080fd5b506100ba61011e565b6040518082815260200191505060405180910390f35b3480156100dc57600080fd5b50610109600480360360208110156100f357600080fd5b8101908080359060200190929190505050610127565b005b6000816000819055506000549050919050565b60008054905090565b600030610132610212565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015610184573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff166360fe47b1836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156101f657600080fd5b505af115801561020a573d6000803e3d6000fd5b505050505050565b604051610302806102238339019056fe608060405234801561001057600080fd5b506040516020806103028339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610271806100916000396000f3fe608060405260043610610046576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b11461004b5780636d4ce63c14610086575b600080fd5b34801561005757600080fd5b506100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100b1565b005b34801561009257600080fd5b5061009b610180565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561014157600080fd5b505af1158015610155573d6000803e3d6000fd5b505050506040513d602081101561016b57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561020557600080fd5b505afa158015610219573d6000803e3d6000fd5b505050506040513d602081101561022f57600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820a537f4c360ce5c6f55523298e314e6456e5c3e02c170563751dfda37d3aeddb30029a165627a7a7230582060396bfff29d2dfc5a9f4216bfba5e24d031d54fd4b26ebebde1a26c59df0c1e0029"),
  27. }
  28. contractDeploymentCount = 100
  29. contractArgumentInitValue = int64(10)
  30. contractArgumentSetValue = int64(15)
  31. contractCreateABIPayloadBytes = contractDeployed.create(big.NewInt(contractArgumentInitValue))
  32. contractSetABIPayloadBytes = contractDeployed.set(contractArgumentSetValue)
  33. encryptedPayloadHashForContractDeployment = common.BytesToEncryptedPayloadHash(common.Hex2Bytes("41a982be5d1f3d92d57487d7d9a905c1d92d3353570730464639affc964bcc83ea24e5b449140a2216ecc3f1d11d3dfd3663c6a9a4f18a7c837a9e4d8bfc81ce"))
  34. encryptedPayloadHashForSetFunction = common.BytesToEncryptedPayloadHash(common.Hex2Bytes("93f769208aa744b6d65310ab191f1fe22f8508ad069810f06889381b89d8c03ade785c7b14230439673f76e08ec84bad611d95d1cbb66dbcf548acbf93db0296"))
  35. slot0OnAccountStorage = common.HexToHash("00")
  36. )
  37. func TestPrefetch_PublicTransaction(t *testing.T) {
  38. var (
  39. engine = ethash.NewFaker()
  40. )
  41. mockTxDataArr := createMockTxData(contractDeploymentCount, Public)
  42. chain, gspec := createBlockchain(params.QuorumTestChainConfig, mockTxDataArr)
  43. minedBlock, futureBlock := createBlocks(chain, gspec, mockTxDataArr, nil)
  44. // Import the canonical chain
  45. chain.InsertChain(types.Blocks{minedBlock})
  46. prefetcher := newStatePrefetcher(gspec.Config, chain, engine)
  47. throwaway, throwawayRepo := createThrowawayStates(minedBlock, chain)
  48. // When
  49. prefetcher.Prefetch(futureBlock, throwaway, throwawayRepo, vm.Config{}, nil)
  50. // Then
  51. for _, data := range mockTxDataArr {
  52. assert.Equal(t, uint64(2), throwaway.GetNonce(data.fromAddress))
  53. assert.Equal(t, common.BigToHash(big.NewInt(contractArgumentSetValue)), throwaway.GetState(data.toAddress, slot0OnAccountStorage))
  54. }
  55. }
  56. func TestPrefetch_PrivateDualStateTransaction(t *testing.T) {
  57. var (
  58. engine = ethash.NewFaker()
  59. mockCtrl = gomock.NewController(t)
  60. )
  61. defer mockCtrl.Finish()
  62. mockptm := createDualStatePrivateTransactionManagerMock(mockCtrl)
  63. saved := private.P
  64. defer func() {
  65. private.P = saved
  66. }()
  67. private.P = mockptm
  68. mockTxDataArr := createMockTxData(contractDeploymentCount, Private)
  69. chain, gspec := createBlockchain(params.QuorumTestChainConfig, mockTxDataArr)
  70. minedBlock, futureBlock := createBlocks(chain, gspec, mockTxDataArr, nil)
  71. // Import the canonical chain
  72. chain.InsertChain(types.Blocks{minedBlock})
  73. prefetcher := newStatePrefetcher(gspec.Config, chain, engine)
  74. throwaway, throwawayRepo := createThrowawayStates(minedBlock, chain)
  75. // When
  76. prefetcher.Prefetch(futureBlock, throwaway, throwawayRepo, vm.Config{}, nil)
  77. // Then
  78. assertPrefetchedDualState(t, mockTxDataArr, throwaway, throwawayRepo)
  79. }
  80. func TestPrefetch_PrivateMPSTransaction(t *testing.T) {
  81. var (
  82. engine = ethash.NewFaker()
  83. mockCtrl = gomock.NewController(t)
  84. )
  85. defer mockCtrl.Finish()
  86. mockptm := createMPSPrivateTransactionManagerMock(mockCtrl)
  87. saved := private.P
  88. defer func() {
  89. private.P = saved
  90. }()
  91. private.P = mockptm
  92. mockTxDataArr := createMockTxData(contractDeploymentCount, Private)
  93. chain, gspec := createBlockchain(params.QuorumMPSTestChainConfig, mockTxDataArr)
  94. minedBlock, futureBlock := createBlocks(chain, gspec, mockTxDataArr, nil)
  95. // Import the canonical chain
  96. chain.InsertChain(types.Blocks{minedBlock})
  97. prefetcher := newStatePrefetcher(gspec.Config, chain, engine)
  98. throwaway, throwawayRepo := createThrowawayStates(minedBlock, chain)
  99. // When
  100. prefetcher.Prefetch(futureBlock, throwaway, throwawayRepo, vm.Config{}, nil)
  101. // Then
  102. assertPrefetchedMPSState(t, mockTxDataArr, throwaway, throwawayRepo)
  103. }
  104. func TestPrefetch_PrivateDualState_PMTTransaction(t *testing.T) {
  105. var (
  106. engine = ethash.NewFaker()
  107. mockCtrl = gomock.NewController(t)
  108. )
  109. defer mockCtrl.Finish()
  110. // Activate PMT
  111. params.QuorumTestChainConfig.PrivacyPrecompileBlock = big.NewInt(0)
  112. defer func() { params.QuorumTestChainConfig.PrivacyPrecompileBlock = nil }()
  113. mockptm := createDualStatePrivateTransactionManagerMock(mockCtrl)
  114. saved := private.P
  115. defer func() {
  116. private.P = saved
  117. }()
  118. private.P = mockptm
  119. mockTxDataArr := createMockTxData(contractDeploymentCount, PMT)
  120. chain, gspec := createBlockchain(params.QuorumTestChainConfig, mockTxDataArr)
  121. minedBlock, futureBlock := createBlocks(chain, gspec, mockTxDataArr, createInnerTransactionHandlerMock(mockptm))
  122. // Import the canonical chain
  123. chain.InsertChain(types.Blocks{minedBlock})
  124. prefetcher := newStatePrefetcher(gspec.Config, chain, engine)
  125. throwaway, throwawayRepo := createThrowawayStates(minedBlock, chain)
  126. // When
  127. prefetcher.Prefetch(futureBlock, throwaway, throwawayRepo, vm.Config{}, nil)
  128. // Then
  129. assertPrefetchedDualState(t, mockTxDataArr, throwaway, throwawayRepo)
  130. }
  131. func TestPrefetch_PrivateMPS_PMTTransaction(t *testing.T) {
  132. var (
  133. engine = ethash.NewFaker()
  134. mockCtrl = gomock.NewController(t)
  135. )
  136. defer mockCtrl.Finish()
  137. // Activate PMT
  138. params.QuorumMPSTestChainConfig.PrivacyPrecompileBlock = big.NewInt(0)
  139. defer func() { params.QuorumMPSTestChainConfig.PrivacyPrecompileBlock = nil }()
  140. mockptm := createMPSPrivateTransactionManagerMock(mockCtrl)
  141. saved := private.P
  142. defer func() {
  143. private.P = saved
  144. }()
  145. private.P = mockptm
  146. mockTxDataArr := createMockTxData(contractDeploymentCount, PMT)
  147. chain, gspec := createBlockchain(params.QuorumMPSTestChainConfig, mockTxDataArr)
  148. minedBlock, futureBlock := createBlocks(chain, gspec, mockTxDataArr, createInnerTransactionHandlerMock(mockptm))
  149. // Import the canonical chain
  150. chain.InsertChain(types.Blocks{minedBlock})
  151. prefetcher := newStatePrefetcher(gspec.Config, chain, engine)
  152. throwaway, throwawayRepo := createThrowawayStates(minedBlock, chain)
  153. // When
  154. prefetcher.Prefetch(futureBlock, throwaway, throwawayRepo, vm.Config{}, nil)
  155. // Then
  156. assertPrefetchedMPSState(t, mockTxDataArr, throwaway, throwawayRepo)
  157. }
  158. // Assert functions
  159. func assertPrefetchedDualState(t *testing.T, mockTxDataArr []*mockTxData, throwaway *state.StateDB, throwawayRepo mps.PrivateStateRepository) {
  160. throwawayPrivateState, _ := throwawayRepo.DefaultState()
  161. for _, data := range mockTxDataArr {
  162. assert.Equal(t, uint64(2), throwaway.GetNonce(data.fromAddress))
  163. assert.Equal(t, common.Hash{}, throwaway.GetState(data.toAddress, slot0OnAccountStorage))
  164. assert.Equal(t, common.BigToHash(big.NewInt(contractArgumentSetValue)), throwawayPrivateState.GetState(data.toAddress, slot0OnAccountStorage))
  165. }
  166. }
  167. func assertPrefetchedMPSState(t *testing.T, mockTxDataArr []*mockTxData, throwaway *state.StateDB, throwawayRepo mps.PrivateStateRepository) {
  168. throwawayDefaultPrivateState, _ := throwawayRepo.DefaultState()
  169. throwawayPS1PrivateState, _ := throwawayRepo.StatePSI(PSI1PSM.ID)
  170. throwawayPS2PrivateState, _ := throwawayRepo.StatePSI(PSI2PSM.ID)
  171. for _, data := range mockTxDataArr {
  172. assert.Equal(t, uint64(2), throwaway.GetNonce(data.fromAddress))
  173. assert.Equal(t, common.Hash{}, throwaway.GetState(data.toAddress, slot0OnAccountStorage))
  174. assert.Equal(t, common.Hash{}, throwawayDefaultPrivateState.GetState(data.toAddress, slot0OnAccountStorage))
  175. assert.Equal(t, common.Hash{}, throwawayPS1PrivateState.GetState(data.toAddress, slot0OnAccountStorage))
  176. assert.Equal(t, common.BigToHash(big.NewInt(contractArgumentSetValue)), throwawayPS2PrivateState.GetState(data.toAddress, slot0OnAccountStorage))
  177. }
  178. }
  179. // Utility types
  180. type txType int
  181. const (
  182. Public txType = iota
  183. Private
  184. PMT
  185. )
  186. type mockTxData struct {
  187. fromAddress common.Address
  188. fromPrivateKey *ecdsa.PrivateKey
  189. toAddress common.Address
  190. funds *big.Int
  191. txType txType
  192. }
  193. // Utility functions
  194. // createThrowawayStates create the StateDBs to be used for the prefetcher to warm up the cached but are thrown away after
  195. func createThrowawayStates(minedBlock *types.Block, chain *BlockChain) (*state.StateDB, mps.PrivateStateRepository) {
  196. throwaway, _ := state.New(minedBlock.Root(), chain.stateCache, chain.snaps)
  197. privateRepo, _ := chain.PrivateStateManager().StateRepository(minedBlock.Root())
  198. throwawayRepo := privateRepo.Copy()
  199. return throwaway, throwawayRepo
  200. }
  201. // createDualStatePrivateTransactionManagerMock create the Tessera mock for Dual State Mode
  202. func createDualStatePrivateTransactionManagerMock(mockCtrl *gomock.Controller) *private.MockPrivateTransactionManager {
  203. mockptm := private.NewMockPrivateTransactionManager(mockCtrl)
  204. mockptm.EXPECT().Receive(encryptedPayloadHashForContractDeployment).Return("", []string{}, contractCreateABIPayloadBytes, nil, nil).AnyTimes()
  205. mockptm.EXPECT().Receive(encryptedPayloadHashForSetFunction).Return("", []string{}, contractSetABIPayloadBytes, nil, nil).AnyTimes()
  206. return mockptm
  207. }
  208. // createMPSPrivateTransactionManagerMock create the Tessera mock for MPS Mode
  209. func createMPSPrivateTransactionManagerMock(mockCtrl *gomock.Controller) *private.MockPrivateTransactionManager {
  210. mockptm := private.NewMockPrivateTransactionManager(mockCtrl)
  211. mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, nil, nil, nil).AnyTimes()
  212. mockptm.EXPECT().Receive(encryptedPayloadHashForContractDeployment).Return("", []string{"BBB"}, contractCreateABIPayloadBytes, nil, nil).AnyTimes()
  213. mockptm.EXPECT().Receive(encryptedPayloadHashForSetFunction).Return("", []string{"BBB"}, contractSetABIPayloadBytes, nil, nil).AnyTimes()
  214. mockptm.EXPECT().HasFeature(privateEngine.MultiplePrivateStates).Return(true).AnyTimes()
  215. mockptm.EXPECT().Groups().Return([]privateEngine.PrivacyGroup{
  216. {
  217. Type: privateEngine.PrivacyGroupResident,
  218. Name: PSI1PSM.Name,
  219. PrivacyGroupId: base64.StdEncoding.EncodeToString([]byte(PSI1PSM.ID)),
  220. Description: "Resident Group 1",
  221. From: "",
  222. Members: []string{"AAA"},
  223. },
  224. {
  225. Type: privateEngine.PrivacyGroupResident,
  226. Name: PSI2PSM.Name,
  227. PrivacyGroupId: base64.StdEncoding.EncodeToString([]byte(PSI2PSM.ID)),
  228. Description: "Resident Group 2",
  229. From: "",
  230. Members: []string{"BBB"},
  231. },
  232. }, nil)
  233. return mockptm
  234. }
  235. // createInnerTransactionHandlerMock create a function that will create the necessary mock to handle the Private Transaction `Receive()` of the private transaction inside a PMT Tx
  236. func createInnerTransactionHandlerMock(mockptm *private.MockPrivateTransactionManager) func(outerTx *types.Transaction, mockTxData *mockTxData) {
  237. return func(outerTx *types.Transaction, mockTxData *mockTxData) {
  238. enclaveHash := common.BytesToEncryptedPayloadHash(outerTx.Data())
  239. mockptm.EXPECT().Receive(enclaveHash).DoAndReturn(func(hash common.EncryptedPayloadHash) (string, []string, []byte, *privateEngine.ExtraMetadata, error) {
  240. innerTx := types.NewTransaction(1, mockTxData.toAddress, common.Big0, uint64(3000000), common.Big0, encryptedPayloadHashForSetFunction.Bytes())
  241. innerTx.SetPrivate()
  242. signedTx, _ := types.SignTx(innerTx, types.QuorumPrivateTxSigner{}, mockTxData.fromPrivateKey)
  243. jsonSignedTx, _ := signedTx.MarshalJSON()
  244. return "", []string{}, jsonSignedTx, nil, nil
  245. }).AnyTimes()
  246. }
  247. }
  248. // createMockTxData create mocked data for transactions
  249. func createMockTxData(n int, txType txType) []*mockTxData {
  250. result := make([]*mockTxData, n)
  251. for i := 0; i < n; i++ {
  252. fromKey, _ := crypto.GenerateKey()
  253. fromAddress := crypto.PubkeyToAddress(fromKey.PublicKey)
  254. result[i] = &mockTxData{
  255. fromPrivateKey: fromKey,
  256. fromAddress: fromAddress,
  257. funds: big.NewInt(1000000000),
  258. txType: txType}
  259. }
  260. return result
  261. }
  262. func createBlockchain(chainConfig *params.ChainConfig, mockTxDataArr []*mockTxData) (*BlockChain, *Genesis) {
  263. var (
  264. engine = ethash.NewFaker()
  265. cacheConfig = *defaultCacheConfig
  266. )
  267. // Disable prefetching. We are going to manually run prefetch
  268. cacheConfig.TrieCleanNoPrefetch = true
  269. allocation := GenesisAlloc{}
  270. for _, data := range mockTxDataArr {
  271. allocation[data.fromAddress] = GenesisAccount{
  272. Balance: data.funds,
  273. Nonce: 0,
  274. }
  275. }
  276. gspec := &Genesis{
  277. Config: chainConfig,
  278. Alloc: allocation,
  279. }
  280. diskdb := rawdb.NewMemoryDatabase()
  281. gspec.MustCommit(diskdb)
  282. vmConfig := vm.Config{
  283. Debug: true,
  284. Tracer: vm.NewJSONLogger(nil, os.Stdout),
  285. }
  286. chain, _ := NewBlockChain(diskdb, &cacheConfig, gspec.Config, engine, vmConfig, nil, nil, nil)
  287. return chain, gspec
  288. }
  289. func createBlocks(chain *BlockChain, gspec *Genesis, mockTxDataArr []*mockTxData, decorateSetTransaction func(*types.Transaction, *mockTxData)) (*types.Block, *types.Block) {
  290. var (
  291. engine = ethash.NewFaker()
  292. temporaryDb = rawdb.NewMemoryDatabase()
  293. )
  294. genesisBlock := gspec.MustCommit(temporaryDb)
  295. minedBlocks, _ := GenerateChain(gspec.Config, genesisBlock, engine, temporaryDb, 1, func(i int, b *BlockGen) {
  296. b.SetCoinbase(common.Address{1})
  297. var signer types.Signer = types.HomesteadSigner{}
  298. for _, mockTxData := range mockTxDataArr {
  299. var data []byte
  300. switch mockTxData.txType {
  301. case Public:
  302. data = contractCreateABIPayloadBytes
  303. case Private, PMT:
  304. data = encryptedPayloadHashForContractDeployment.Bytes()
  305. }
  306. createTransaction := types.NewContractCreation(0, common.Big0, uint64(3000000), common.Big0, data)
  307. switch mockTxData.txType {
  308. case Private, PMT:
  309. createTransaction.SetPrivate()
  310. signer = types.QuorumPrivateTxSigner{}
  311. }
  312. signedTx, _ := types.SignTx(createTransaction, signer, mockTxData.fromPrivateKey)
  313. b.AddTxWithChain(chain, signedTx)
  314. // save the contract address to use when calling `set()`
  315. mockTxData.toAddress = b.receipts[0].ContractAddress
  316. }
  317. })
  318. futureBlocks, _ := GenerateChain(gspec.Config, minedBlocks[0], engine, temporaryDb, 1, func(i int, b *BlockGen) {
  319. b.SetCoinbase(common.Address{1})
  320. var signer types.Signer = types.HomesteadSigner{}
  321. for _, mockTxData := range mockTxDataArr {
  322. var data []byte
  323. var setTransaction *types.Transaction
  324. switch mockTxData.txType {
  325. case Public:
  326. data = contractSetABIPayloadBytes
  327. setTransaction = types.NewTransaction(1, mockTxData.toAddress, common.Big0, uint64(3000000), common.Big0, data)
  328. case Private:
  329. data = encryptedPayloadHashForSetFunction.Bytes()
  330. setTransaction = types.NewTransaction(1, mockTxData.toAddress, common.Big0, uint64(3000000), common.Big0, data)
  331. setTransaction.SetPrivate()
  332. signer = types.QuorumPrivateTxSigner{}
  333. case PMT:
  334. data = common.LeftPadBytes(mockTxData.toAddress.Bytes(), 64)
  335. setTransaction = types.NewTransaction(1, common.QuorumPrivacyPrecompileContractAddress(), common.Big0, uint64(3000000), common.Big0, data)
  336. }
  337. if decorateSetTransaction != nil {
  338. decorateSetTransaction(setTransaction, mockTxData)
  339. }
  340. signedTx, _ := types.SignTx(setTransaction, signer, mockTxData.fromPrivateKey)
  341. b.AddTxWithChain(chain, signedTx)
  342. }
  343. })
  344. return minedBlocks[0], futureBlocks[0]
  345. }
  346. const (
  347. contractDeployedDefinition = `
  348. [
  349. {
  350. "constant": false,
  351. "inputs": [
  352. {
  353. "name": "newValue",
  354. "type": "uint256"
  355. }
  356. ],
  357. "name": "set",
  358. "outputs": [
  359. {
  360. "name": "",
  361. "type": "uint256"
  362. }
  363. ],
  364. "payable": false,
  365. "stateMutability": "nonpayable",
  366. "type": "function"
  367. },
  368. {
  369. "constant": true,
  370. "inputs": [],
  371. "name": "get",
  372. "outputs": [
  373. {
  374. "name": "",
  375. "type": "uint256"
  376. }
  377. ],
  378. "payable": false,
  379. "stateMutability": "view",
  380. "type": "function"
  381. },
  382. {
  383. "constant": false,
  384. "inputs": [
  385. {
  386. "name": "newValue",
  387. "type": "uint256"
  388. }
  389. ],
  390. "name": "newContractC2",
  391. "outputs": [],
  392. "payable": false,
  393. "stateMutability": "nonpayable",
  394. "type": "function"
  395. },
  396. {
  397. "inputs": [
  398. {
  399. "name": "initVal",
  400. "type": "uint256"
  401. }
  402. ],
  403. "payable": false,
  404. "stateMutability": "nonpayable",
  405. "type": "constructor"
  406. }
  407. ]
  408. `
  409. )