diff --git a/docs/content/developer/iota-evm/solo/getting-started.md b/docs/content/developer/iota-evm/solo/getting-started.md index 46f2a9480ae..3c5817fdc56 100644 --- a/docs/content/developer/iota-evm/solo/getting-started.md +++ b/docs/content/developer/iota-evm/solo/getting-started.md @@ -21,8 +21,10 @@ validate real smart contracts and entire inter-chain protocols before deploying ### Prerequisites -[Go (version 1.20)](https://tip.golang.org/doc/go1.20). As _Solo_ tests are written in Go, you must -[install Go](https://go.dev/doc/install). +- [Go (version 1.20)](https://tip.golang.org/doc/go1.20). As _Solo_ tests are written in Go, you must + [install Go](https://go.dev/doc/install). + +- [Docker](https://www.docker.com/). Solo will run a local IOTA network in a Docker container ### Access the Solo Framework diff --git a/docs/content/developer/iota-evm/solo/how-tos/first-example.md b/docs/content/developer/iota-evm/solo/how-tos/first-example.md index e2e8c9b33d7..6306098bbd3 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/first-example.md +++ b/docs/content/developer/iota-evm/solo/how-tos/first-example.md @@ -16,29 +16,48 @@ The following is an example of a _Solo_ test. It deploys a new chain and invokes [`root`](../../references/core-contracts/root.md) and [`governance`](../../references/core-contracts/governance.md) [core contracts](../../references/core-contracts/overview.md). +:::info L1 Network + +To run the tests a local IOTA network is required. That is what + ```go -import ( - "testing" +func TestMain(m *testing.M) { + l1starter.TestMain(m) +} +``` + +is for. You will need to call it once before running any tests that use the Solo framework. - "github.com/iotaledger/wasp/packages/solo" - "github.com/iotaledger/wasp/packages/vm/core/corecontracts" - "github.com/stretchr/testify/require" +::: + +```go +package solo_test + +import ( + "testing" + "github.com/iotaledger/wasp/packages/solo" + "github.com/iotaledger/wasp/packages/vm/core/corecontracts" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/packages/testutil/l1starter" ) +func TestMain(m *testing.M) { + l1starter.TestMain(m) +} + func TestTutorialFirst(t *testing.T) { - env := solo.New(t) - chain := env.NewChain() - - // calls views governance::ViewGetChainInfo and root:: ViewGetContractRecords - chainID, chainOwnerID, coreContracts := chain.GetInfo() - // assert that all core contracts are deployed - require.EqualValues(t, len(corecontracts.All), len(coreContracts)) - - t.Logf("chain ID: %s", chainID.String()) - t.Logf("chain owner ID: %s", chainOwnerID.String()) - for hname, rec := range coreContracts { - t.Logf(" Core contract %q: %s", rec.Name, hname) - } + env := solo.New(t) + chain := env.NewChain() + // calls views governance::ViewGetChainInfo and root:: ViewGetContractRecords + chainID, chainOwnerID, coreContracts := chain.GetInfo() + // assert that all core contracts are deployed + require.GreaterOrEqual(t, len(coreContracts), len(corecontracts.All)) + + t.Logf("chain ID: %s", chainID.String()) + t.Logf("chain owner ID: %s", chainOwnerID.String()) + for hname, rec := range coreContracts { + t.Logf(" Core contract %q: %s", rec.Name, hname) + } } ``` @@ -46,28 +65,33 @@ The output of the test will be something like this: ```log === RUN TestTutorialFirst -29:43.383770108 INFO TestTutorialFirst.db dbmanager/dbmanager.go:64 creating new in-memory database for: CHAIN_REGISTRY -29:43.383957435 INFO TestTutorialFirst solo/solo.go:162 Solo environment has been created: logical time: 00:01.001000000, time step: 1ms -29:43.384671943 INFO TestTutorialFirst solo/solo.go:236 deploying new chain 'tutorial1'. ID: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd, state controller address: tgl1qpk70349ftcpvlt6lnn0437p63wt7w2ejvlkw93wkkt0kc39f2wpvuv73ea -29:43.384686865 INFO TestTutorialFirst solo/solo.go:238 chain 'tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd'. state controller address: tgl1qpk70349ftcpvlt6lnn0437p63wt7w2ejvlkw93wkkt0kc39f2wpvuv73ea -29:43.384698704 INFO TestTutorialFirst solo/solo.go:239 chain 'tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd'. originator address: tgl1qq93jh7dsxq3lznajgtq33v26rt0pz0rs0rwar4jahahp6h2hh9jy4nc52k -29:43.384709967 INFO TestTutorialFirst.db dbmanager/dbmanager.go:64 creating new in-memory database for: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd -29:43.384771911 INFO TestTutorialFirst solo/solo.go:244 chain 'tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd'. origin state commitment: c4f09061cd63ea506f89b7cbb3c6e0984f124158 -29:43.417023624 INFO TestTutorialFirst solo/solo.go:171 solo publisher: state [tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd 1 1 0-6c7ff6bc5aaa3af12f9b6b7c43dcf557175ac251418df562f7ec4ff092e84d4f 0000000000000000000000000000000000000000000000000000000000000000] -29:43.417050354 INFO TestTutorialFirst solo/solo.go:171 solo publisher: request_out [tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd 0-11232aa47639429b83faf79547c6bf615bd65aa461f243c89e4073b792ac89b7 1 1] -29:43.417056290 INFO TestTutorialFirst.tutorial1 solo/run.go:156 state transition --> #1. Requests in the block: 1. Outputs: 1 -29:43.417179099 INFO TestTutorialFirst.tutorial1 solo/run.go:176 REQ: 'tx/0-11232aa47639429b83faf79547c6bf615bd65aa461f243c89e4073b792ac89b7' -29:43.417196814 INFO TestTutorialFirst.tutorial1 solo/solo.go:301 chain 'tutorial1' deployed. Chain ID: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd - tutorial_test.go:20: chain ID: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd - tutorial_test.go:21: chain owner ID: tgl1qq93jh7dsxq3lznajgtq33v26rt0pz0rs0rwar4jahahp6h2hh9jy4nc52k - tutorial_test.go:23: Core contract "blob": fd91bc63 - tutorial_test.go:23: Core contract "governance": 17cf909f - tutorial_test.go:23: Core contract "errors": 8f3a8bb3 - tutorial_test.go:23: Core contract "evm": 07cb02c1 - tutorial_test.go:23: Core contract "accounts": 3c4b5e02 - tutorial_test.go:23: Core contract "root": cebf5908 - tutorial_test.go:23: Core contract "blocklog": f538ef2b ---- PASS: TestTutorialFirst (0.03s) +config file .testconfig not found - using default values +02:54.102456000 INFO TestTutorialFirst WaitForNextVersionForTesting: Found the updated version of obj{id=0x0316f37b5651ca53efd28835209b5054636b9ae40c602db9f442eeb3d2843509, version=2, digest=8zFknGz5Jn71mBfRgGpGVN9DG6i5RWvG5cUi69PutcZY}, which is: {0x0316f37b5651ca53efd28835209b5054636b9ae40c602db9f442eeb3d2843509 3 BgPrbjBJKae1ZTLPxyktpJ3reJXPqR5zQegDgARuSTDw} +02:54.102485000 INFO TestTutorialFirst Chain Originator address: &{0x140000d2e10 0x140000d2e40} +02:54.102504000 INFO TestTutorialFirst GAS COIN BEFORE PULL: obj{id=0x24b93a63294dd2d601787bc2c6a0c3c6cdc8bbff5a256fcd9bf0b44692b6b2c3, version=3, digest=6sfviRVcVqTqZkigr2PqUbP62aG6a6KS5TbaSyZ7TB9A} +02:54.102595000 INFO TestTutorialFirst.L1ParamsFetcher Fetching latest L1Params... +02:54.442070000 INFO TestTutorialFirst WaitForNextVersionForTesting: Found the updated version of obj{id=0x0316f37b5651ca53efd28835209b5054636b9ae40c602db9f442eeb3d2843509, version=3, digest=BgPrbjBJKae1ZTLPxyktpJ3reJXPqR5zQegDgARuSTDw}, which is: {0x0316f37b5651ca53efd28835209b5054636b9ae40c602db9f442eeb3d2843509 4 4cg6HjxVSUsHfaZCgT2dHVr3DmUcqBg5BfKtXtNdFF94} +02:54.442118000 INFO TestTutorialFirst deployed chain 'chain1' - ID: 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 - anchor owner: 0x67fc46395ed92449249dc61336ad51eef1b6501cec11f26f2e305e458d576c65 - chain admin: 0xf752b522fd4ef6105d2d15a21956327bb7492258d4276fd71e78060282460a42 - origin trie root: 476f6131eedd2379f8cd5cd363cf48fc0416a3ed +02:54.442140000 INFO TestTutorialFirst.chain1 chain 'chain1' deployed. Chain ID: 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 +02:54.895435000 INFO TestTutorialFirst WaitForNextVersionForTesting: Found the updated version of obj{id=0x24b93a63294dd2d601787bc2c6a0c3c6cdc8bbff5a256fcd9bf0b44692b6b2c3, version=3, digest=6sfviRVcVqTqZkigr2PqUbP62aG6a6KS5TbaSyZ7TB9A}, which is: {0x24b93a63294dd2d601787bc2c6a0c3c6cdc8bbff5a256fcd9bf0b44692b6b2c3 5 DQokmMDn38zEZifMHsVGd6GbsJ8xxUWadYyzyYPhcrak} +02:54.896287000 INFO TestTutorialFirst solo publisher: new_block 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 | - (new_block) +02:54.896298000 INFO TestTutorialFirst.chain1 state transition --> #1. Requests in the block: 1 +02:54.896435000 INFO TestTutorialFirst solo publisher: receipt 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 | 0xf752b522fd4ef6105d2d15a21956327bb7492258d4276fd71e78060282460a42 (receipt) +02:54.896481000 INFO TestTutorialFirst solo publisher: block_events 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 | - (block_events) +02:54.897057000 INFO TestTutorialFirst.chain1 REQ: 'tx/0xa47f42f8d7c4c924b04ebc54e56f028a21d3a16049df2f888ff2e1b35fa98b0b' + tutorial_test.go:30: chain ID: 0x0e3ad1d73c790603e4239e9db4d1c0f79cf6e69956c89bee7926ebc6b8fa6aa5 + tutorial_test.go:31: chain owner ID: 0xf752b522fd4ef6105d2d15a21956327bb7492258d4276fd71e78060282460a42 + tutorial_test.go:33: Core contract "root": 0xcebf5908 + tutorial_test.go:33: Core contract "governance": 0x17cf909f + tutorial_test.go:33: Core contract "testcore": 0x370d33ad + tutorial_test.go:33: Core contract "errors": 0x8f3a8bb3 + tutorial_test.go:33: Core contract "evm": 0x07cb02c1 + tutorial_test.go:33: Core contract "testerrors": 0x6cb85de2 + tutorial_test.go:33: Core contract "accounts": 0x3c4b5e02 + tutorial_test.go:33: Core contract "blocklog": 0xf538ef2b + tutorial_test.go:33: Core contract "ManyEventsContract": 0x19cdb859 + tutorial_test.go:33: Core contract "inccounter": 0xaf2438e9 +--- PASS: TestTutorialFirst (5.70s) ``` :::note diff --git a/docs/content/developer/iota-evm/solo/how-tos/the-l1-ledger.md b/docs/content/developer/iota-evm/solo/how-tos/the-l1-ledger.md index 863111f2735..799eb84f062 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/the-l1-ledger.md +++ b/docs/content/developer/iota-evm/solo/how-tos/the-l1-ledger.md @@ -12,32 +12,14 @@ teams: # The L1 Ledger -IOTA Smart Contracts work as a **layer 2** (**L2**) extension of the _IOTA Multi-Asset Ledger_, **layer 1** (**L1**). -The specifics of the ledger is outside the scope of this documentation; for now it is sufficient to know that the ledger -contains balances of different kinds of assets (base tokens and _NFT_s) locked in addresses. -Assets can only be moved on the ledger by unlocking the corresponding address with its private key. - -For example: - -```log -Address: iota1pr7vescn4nqc9lpvv37unzryqc43vw5wuf2zx8tlq2wud0369hjjugg54mf - IOTA: 4012720 - Native token 0x08fcccc313acc182fc2c647dc98864062b163a8ee254231d7f029dc6be3a2de52e0100000000: 100 - NFT 0x94cd51b79d9608ed6e38780d48e9fc8c295b893077739b28ce591c45b33dec44 -``` - -In this example, the address owns some base tokens (IOTA), 100 units of a native token with ID `0x08fc...`, and an NFT -with ID `0x94cd...`. - -You can find more information about the ledger in the -[Multi-Asset Ledger TIP](https://github.com/lzpap/tips/blob/master/tips/TIP-0018/tip-0018.md). +IOTA EVM works as a **layer 2** (**L2**) extension of the _IOTA Move Ledger_, **layer 1** (**L1**). +The address on L1 can own different coins or other [objects](../../../iota-101/objects/object-model.mdx). In normal operation, the L2 state is maintained by a committee of Wasp _nodes_. The L1 ledger is provided and -maintained by a network of [Hornet](https://github.com/iotaledger/hornet) nodes, which is a distributed implementation -of the IOTA Multi-Asset Ledger. +maintained by a network of [IOTA](../../../../operator/full-node/overview.mdx) nodes. -The Solo environment implements a standalone in-memory ledger, simulating the behavior of a real L1 ledger without the -need to run a network of Hornet nodes. +The Solo environment runs a local network, simulating the behavior of a real L1 ledger without the +need to run a network of IOTA nodes. The following example creates a new wallet (private/public key pair) and requests some base tokens from the faucet: @@ -45,10 +27,10 @@ The following example creates a new wallet (private/public key pair) and request func TestTutorialL1(t *testing.T) { env := solo.New(t) _, userAddress := env.NewKeyPairWithFunds(env.NewSeedFromIndex(1)) - t.Logf("address of the user is: %s", userAddress.Bech32(parameters.L1.Protocol.Bech32HRP)) + t.Logf("address of the user is: %s", userAddress) numBaseTokens := env.L1BaseTokens(userAddress) t.Logf("balance of the user is: %d base tokens", numBaseTokens) - env.AssertL1BaseTokens(userAddress, utxodb.FundsFromFaucetAmount) + env.AssertL1BaseTokens(userAddress, iotaclient.FundsFromFaucetAmount) } ``` @@ -56,15 +38,12 @@ The _output_ of the test is: ```log === RUN TestTutorialL1 -47:49.136622566 INFO TestTutorialL1.db dbmanager/dbmanager.go:64 creating new in-memory database for: CHAIN_REGISTRY -47:49.136781104 INFO TestTutorialL1 solo/solo.go:162 Solo environment has been created: logical time: 00:01.001000000, time step: 1ms - tutorial_test.go:32: address of the user is: tgl1qp5d8zm9rr9rcae2hq95plx0rquy5gu2mpedurm2kze238neuhh5csjngz0 - tutorial_test.go:34: balance of the user is: 1000000000 base tokens ---- PASS: TestTutorialL1 (0.00s) + wiki_test.go:29: address of the user is: 0x464b5a22a1d5e40ae9f8af129cb81a777c4fae97737754b8fb481d3ed7d84c31 + wiki_test.go:31: balance of the user is: 10000000000 base tokens +--- PASS: TestTutorialL1 (2.28s) ``` The L1 ledger in Solo can be accessed via the Solo instance called `env`. The ledger is unique for the lifetime of the Solo environment. -Even if several L2 chains are deployed during the test, all of them will live on the same L1 ledger; this way Solo makes -it possible to test cross-chain transactions. +Even if several L2 chains are deployed during the test, all of them will live on the same L1 ledger; this way Solo makes it possible to test cross-chain transactions. (Note that in the test above we did not deploy any chains: the L1 ledger exists independently of any chains.)