Documentation ¶
Overview ¶
Package 'solo' is a development tool to write unit tests for IOTA Smart Contracts (ISCP).
A development tool ¶
The package is intended for developers of smart contracts as well as contributors to the development of the ISCP and the Wasp node itself.
Normally, the smart contract is developed and tested in the 'solo' environment before trying it out on the network of Wasp nodes. Running and testing the smart contract on 'solo' does not require to run the Wasp nodes nor committee of nodes: just ordinary 'go test' environment.
Native environment ¶
'solo' shares the same code of Virtual Machine with the Wasp node. This guarantees that smart contract programs can later be deployed on chains which are run by the network of Wasp nodes without any modifications.
The 'solo' environment uses in-memory UTXO ledger to validate and store transactions. The UTXODB mocks Goshimmer UTXO ledger, it uses same value transaction structure, colored tokens, signature schemes as well as transaction and signature validation as in Value Tangle of Goshimmer (Pollen release). The only difference with the Value Tangle is that UTXODB provides full synchronicity of ledger updates.
The virtual state (key/value database) in 'solo' is an in-memory database. It provides exactly the same interface of access to it as the database of the Wasp node.
Writing smart contracts ¶
The smart contracts are usually written in Rust using Rust libraries provided in the 'wasplib' repository at https://github.com/iotaledger/wasplib. Rust code is compiled into the WebAssembly (Wasm) binary. The Wasm binary is uploaded by 'solo' onto the chain and then loaded into the VM and executed.
Another option to write and run ISCP smart contracts is to use the native Go environment of the Wasp node and 'Sandbox' interface, provided by the Wasp for the VM: the "hardcoded" mode. The latter approach is not normally used to develop apps, however is used for the 4 builtin contracts which constitutes the core of the ISCP chains. The approach to write "hardcoded" smart contracts may also be very useful for the development and debugging of the smart contract logic in IDE such as GoLand, before writing it as a Rust/Wasm smart contract.
Example test ¶
The following example deploys chain and retrieves basic info from the deployed chain. It is expected 4 core contracts deployed on it by default and the test prints them.
func TestSolo1(t *testing.T) { env := solo.New(t, false, false) chain := env.NewChain(nil, "ex1") chainInfo, coreContracts := chain.GetInfo() // calls view root::GetInfo require.EqualValues(t, 4, len(coreContracts)) // 4 core contracts deployed by default t.Logf("chainID: %s", chainInfo.ChainID) t.Logf("chain owner ID: %s", chainInfo.ChainOwnerID) for hname, rec := range coreContracts { t.Logf(" Core contract '%s': %s", rec.Name, iscp.NewContractID(chain.ChainID, hname)) } }
will produce the following output:
=== RUN TestSolo1 34:37.415 INFO TestSolo1 solo/solo.go:153 deploying new chain 'ex1' 34:37.419 INFO TestSolo1.ex1 vmcontext/runreq.go:177 eventlog -> '[req] [0]Ei4d6oUbcgSPnmpTupeLaTNoNf1hRu8ZfZfmw2KFKzZm: Ok' 34:37.420 INFO TestSolo1.ex1 solo/run.go:75 state transition #0 --> #1. Requests in the block: 1. Posted: 0 34:37.420 INFO TestSolo1 solo/clock.go:44 ClockStep: logical clock advanced by 1ms 34:37.420 INFO TestSolo1.ex1 solo/solo.go:233 chain 'ex1' deployed. Chain ID: aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3 34:37.420 INFO TestSolo1.ex1 solo/req.go:145 callView: root::getChainInfo solo_test.go:18: chainID: aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3 solo_test.go:19: chain owner ID: A/UrYEv4Yh7WU1M29cKq73tb2CUx8EYXfJt6JZn5srw19U solo_test.go:21: Core contract 'accounts': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::3c4b5e02 solo_test.go:21: Core contract 'blob': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::fd91bc63 solo_test.go:21: Core contract 'root': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::cebf5908 solo_test.go:21: Core contract 'eventlog': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::661aa7d8 --- PASS: TestSolo1 (0.01s)
Index ¶
- Constants
- type CallParams
- func (r *CallParams) NewRequestOffLedger(keyPair *ed25519.KeyPair) *request.OffLedger
- func (r *CallParams) WithIotas(amount uint64) *CallParams
- func (r *CallParams) WithMint(targetAddress ledgerstate.Address, amount uint64) *CallParams
- func (r *CallParams) WithTransfer(col colored.Color, amount uint64) *CallParams
- func (r *CallParams) WithTransfers(transfer colored.Balances) *CallParams
- type Chain
- func (ch *Chain) AddAllowedStateController(addr ledgerstate.Address, keyPair *ed25519.KeyPair) error
- func (ch *Chain) AssertAccountBalance(agentID *iscp.AgentID, col colored.Color, bal uint64)
- func (ch *Chain) AssertCommonAccountIotas(bal uint64)
- func (ch *Chain) AssertIotas(agentID *iscp.AgentID, bal uint64)
- func (ch *Chain) AssertOwnersBalance(col colored.Color, bal uint64)
- func (ch *Chain) AssertTotalAssets(col colored.Color, bal uint64)
- func (ch *Chain) AssertTotalIotas(bal uint64)
- func (ch *Chain) CallView(scName, funName string, params ...interface{}) (dict.Dict, error)
- func (ch *Chain) CheckAccountLedger()
- func (ch *Chain) CheckChain()
- func (ch *Chain) CheckControlAddresses()
- func (ch *Chain) CommonAccount() *iscp.AgentID
- func (ch *Chain) ContractAgentID(name string) *iscp.AgentID
- func (ch *Chain) DeployContract(keyPair *ed25519.KeyPair, name string, programHash hashing.HashValue, ...) error
- func (ch *Chain) DeployWasmContract(keyPair *ed25519.KeyPair, name, fname string, params ...interface{}) error
- func (ch *Chain) DumpAccounts() string
- func (ch *Chain) FindContract(scName string) (*root.ContractRecord, error)
- func (ch *Chain) GetAccountBalance(agentID *iscp.AgentID) colored.Balances
- func (ch *Chain) GetAccounts() []*iscp.AgentID
- func (ch *Chain) GetAllowedStateControllerAddresses() []ledgerstate.Address
- func (ch *Chain) GetBlobInfo(blobHash hashing.HashValue) (map[string]uint32, bool)
- func (ch *Chain) GetBlockInfo(blockIndex uint32) (*blocklog.BlockInfo, error)
- func (ch *Chain) GetChainOutput() *ledgerstate.AliasOutput
- func (ch *Chain) GetCommonAccountBalance() colored.Balances
- func (ch *Chain) GetCommonAccountIotas() uint64
- func (ch *Chain) GetControlAddresses() *blocklog.ControlAddresses
- func (ch *Chain) GetEventsForBlock(blockIndex uint32) ([]string, error)
- func (ch *Chain) GetEventsForContract(name string) ([]string, error)
- func (ch *Chain) GetEventsForRequest(reqID iscp.RequestID) ([]string, error)
- func (ch *Chain) GetFeeInfo(contactName string) (colored.Color, uint64, uint64)
- func (ch *Chain) GetInfo() (*iscp.ChainID, *iscp.AgentID, map[iscp.Hname]*root.ContractRecord)
- func (ch *Chain) GetLatestBlockInfo() *blocklog.BlockInfo
- func (ch *Chain) GetOnChainLedger() map[string]colored.Balances
- func (ch *Chain) GetOnChainLedgerString() string
- func (ch *Chain) GetRequestIDsForBlock(blockIndex uint32) []iscp.RequestID
- func (ch *Chain) GetRequestReceipt(reqID iscp.RequestID) (*blocklog.RequestReceipt, uint32, uint16, bool)
- func (ch *Chain) GetRequestReceiptsForBlock(blockIndex uint32) []*blocklog.RequestReceipt
- func (ch *Chain) GetRequestReceiptsForBlockRange(fromBlockIndex, toBlockIndex uint32) []*blocklog.RequestReceipt
- func (ch *Chain) GetRequestReceiptsForBlockRangeAsStrings(fromBlockIndex, toBlockIndex uint32) []string
- func (ch *Chain) GetTotalAssets() colored.Balances
- func (ch *Chain) GetTotalIotas() uint64
- func (ch *Chain) GetWasmBinary(progHash hashing.HashValue) ([]byte, error)
- func (ch *Chain) GrantDeployPermission(keyPair *ed25519.KeyPair, deployerAgentID *iscp.AgentID) error
- func (ch *Chain) IsRequestProcessed(reqID iscp.RequestID) bool
- func (ch *Chain) MempoolInfo() chain.MempoolInfo
- func (ch *Chain) PostRequestOffLedger(req *CallParams, keyPair *ed25519.KeyPair) (dict.Dict, error)
- func (ch *Chain) PostRequestSync(req *CallParams, keyPair *ed25519.KeyPair) (dict.Dict, error)
- func (ch *Chain) PostRequestSyncTx(req *CallParams, keyPair *ed25519.KeyPair) (*ledgerstate.Transaction, dict.Dict, error)
- func (ch *Chain) RemoveAllowedStateController(addr ledgerstate.Address, keyPair *ed25519.KeyPair) error
- func (ch *Chain) RequestFromParamsToLedger(req *CallParams, keyPair *ed25519.KeyPair) (*ledgerstate.Transaction, iscp.RequestID, error)
- func (ch *Chain) RevokeDeployPermission(keyPair *ed25519.KeyPair, deployerAgentID *iscp.AgentID) error
- func (ch *Chain) RotateStateController(newStateAddr ledgerstate.Address, ...) error
- func (ch *Chain) String() string
- func (ch *Chain) UploadBlob(keyPair *ed25519.KeyPair, params ...interface{}) (ret hashing.HashValue, err error)
- func (ch *Chain) UploadBlobOptimized(optimalSize int, keyPair *ed25519.KeyPair, params ...interface{}) (ret hashing.HashValue, err error)
- func (ch *Chain) UploadWasm(keyPair *ed25519.KeyPair, binaryCode []byte) (ret hashing.HashValue, err error)
- func (ch *Chain) UploadWasmFromFile(keyPair *ed25519.KeyPair, fileName string) (ret hashing.HashValue, err error)
- func (ch *Chain) WaitForRequestsThrough(numReq int, maxWait ...time.Duration) bool
- type Solo
- func (env *Solo) AddToLedger(tx *ledgerstate.Transaction) error
- func (env *Solo) AdvanceClockBy(step time.Duration)
- func (env *Solo) AdvanceClockTo(ts time.Time)
- func (env *Solo) AssertAddressBalance(addr ledgerstate.Address, col colored.Color, expected uint64)
- func (env *Solo) AssertAddressIotas(addr ledgerstate.Address, expected uint64)
- func (env *Solo) ClockStep()
- func (env *Solo) EnablePublisher(enable bool)
- func (env *Solo) EnqueueRequests(tx *ledgerstate.Transaction)
- func (env *Solo) GetAddressBalance(addr ledgerstate.Address, col colored.Color) uint64
- func (env *Solo) GetAddressBalances(addr ledgerstate.Address) colored.Balances
- func (env *Solo) LogicalTime() time.Time
- func (env *Solo) MintTokens(wallet *ed25519.KeyPair, amount uint64) (colored.Color, error)
- func (env *Solo) NewChain(chainOriginator *ed25519.KeyPair, name string, ...) *Chain
- func (env *Solo) NewKeyPair(seedOpt ...*ed25519.Seed) (*ed25519.KeyPair, ledgerstate.Address)
- func (env *Solo) NewKeyPairWithFunds(seed ...*ed25519.Seed) (*ed25519.KeyPair, ledgerstate.Address)
- func (env *Solo) NewSeedFromIndex(index int) *ed25519.Seed
- func (env *Solo) PutBlobDataIntoRegistry(data []byte) hashing.HashValue
- func (env *Solo) RequestsForChain(tx *ledgerstate.Transaction, chainID *iscp.ChainID) ([]iscp.Request, error)
- func (env *Solo) SetTimeStep(step time.Duration)
- func (env *Solo) SyncLog()
- func (env *Solo) WaitPublisher()
- func (env *Solo) WithNativeContract(c *coreutil.ContractProcessor) *Solo
- type TestContext
Constants ¶
const ( OptimizeUpload = true OptimalBlobSize = 512 )
const ( Saldo = utxodb.RequestFundsAmount DustThresholdIotas = uint64(1) ChainDustThreshold = uint64(100) MaxRequestsInBlock = 100 )
Saldo is the default amount of tokens returned by the UTXODB faucet which is therefore the amount returned by NewKeyPairWithFunds() and such
const DefaultTimeStep = 1 * time.Millisecond
DefaultTimeStep is a default step for the logical clock for each PostRequestSync call.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CallParams ¶
type CallParams struct {
// contains filtered or unexported fields
}
func NewCallParams ¶
func NewCallParams(scName, funName string, params ...interface{}) *CallParams
NewCallParams creates structure which wraps in one object call parameters, used in PostRequestSync and callViewFull calls:
- 'scName' is a a name of the target smart contract
- 'funName' is a name of the target entry point (the function) of he smart contract program
- 'params' is either a dict.Dict, or a sequence of pairs 'paramName', 'paramValue' which constitute call parameters The 'paramName' must be a string and 'paramValue' must different types (encoded based on type)
With the WithTransfers the CallParams structure may be complemented with attached colored tokens sent together with the request
func NewCallParamsFromDic ¶
func NewCallParamsFromDic(scName, funName string, par dict.Dict) *CallParams
func NewCallParamsOptimized ¶
func (*CallParams) NewRequestOffLedger ¶ added in v0.2.0
func (r *CallParams) NewRequestOffLedger(keyPair *ed25519.KeyPair) *request.OffLedger
NewRequestOffLedger creates off-ledger request from parameters
func (*CallParams) WithIotas ¶ added in v0.2.0
func (r *CallParams) WithIotas(amount uint64) *CallParams
func (*CallParams) WithMint ¶ added in v0.2.0
func (r *CallParams) WithMint(targetAddress ledgerstate.Address, amount uint64) *CallParams
WithMint adds additional mint proof
func (*CallParams) WithTransfer ¶
func (r *CallParams) WithTransfer(col colored.Color, amount uint64) *CallParams
WithTransfer is a shorthand for the most often used case where only a single color is transferred by WithTransfers
func (*CallParams) WithTransfers ¶
func (r *CallParams) WithTransfers(transfer colored.Balances) *CallParams
WithTransfers complement CallParams structure with the colored balances of tokens in the form of a collection of pairs 'color': 'balance'
type Chain ¶
type Chain struct { // Env is a pointer to the global structure of the 'solo' test Env *Solo // Name is the name of the chain Name string // StateControllerKeyPair signature scheme of the chain address, the one used to control funds owned by the chain. // In Solo it is Ed25519 signature scheme (in full Wasp environment is is a BLS address) StateControllerKeyPair *ed25519.KeyPair StateControllerAddress ledgerstate.Address // OriginatorKeyPair the signature scheme used to create the chain (origin transaction). // It is a default signature scheme in many of 'solo' calls which require private key. OriginatorKeyPair *ed25519.KeyPair // ChainID is the ID of the chain (in this version alias of the ChainAddress) ChainID *iscp.ChainID // OriginatorAddress is the alias for OriginatorKeyPair.Address() OriginatorAddress ledgerstate.Address // OriginatorAgentID is the OriginatorAddress represented in the form of AgentID OriginatorAgentID *iscp.AgentID // ValidatorFeeTarget is the agent ID to which all fees are accrued. By default is its equal to OriginatorAddress ValidatorFeeTarget *iscp.AgentID // State ia an interface to access virtual state of the chain: the collection of key/value pairs State state.VirtualStateAccess GlobalSync coreutil.ChainStateSync StateReader state.OptimisticStateReader // Log is the named logger of the chain Log *logger.Logger // contains filtered or unexported fields }
Chain represents state of individual chain. There may be several parallel instances of the chain in the 'solo' test
func (*Chain) AddAllowedStateController ¶ added in v0.2.0
func (ch *Chain) AddAllowedStateController(addr ledgerstate.Address, keyPair *ed25519.KeyPair) error
AddAllowedStateController adds the address to the allowed state controlled address list
func (*Chain) AssertAccountBalance ¶
AssertAccountBalance asserts the on-chain account balance controlled by agentID for specific color
func (*Chain) AssertCommonAccountIotas ¶ added in v0.2.0
func (*Chain) AssertIotas ¶ added in v0.2.0
func (*Chain) AssertOwnersBalance ¶ added in v0.2.0
AssertAccountBalance asserts the on-chain account balance controlled by agentID for specific color
func (*Chain) AssertTotalAssets ¶ added in v0.2.0
AssertAccountBalance asserts the on-chain account balance controlled by agentID for specific color
func (*Chain) AssertTotalIotas ¶ added in v0.2.0
func (*Chain) CallView ¶
CallView calls the view entry point of the smart contract. The call params should be either a dict.Dict, or pairs of ('paramName', 'paramValue') where 'paramName' is a string and 'paramValue' must be of type accepted by the 'codec' package
func (*Chain) CheckAccountLedger ¶
func (ch *Chain) CheckAccountLedger()
CheckAccountLedger check integrity of the on-chain ledger. Sum of all accounts must be equal to total assets
func (*Chain) CheckChain ¶
func (ch *Chain) CheckChain()
CheckChain checks fundamental integrity of the chain
func (*Chain) CheckControlAddresses ¶ added in v0.2.0
func (ch *Chain) CheckControlAddresses()
func (*Chain) CommonAccount ¶ added in v0.2.0
CommonAccount return the agentID of the common account (controlled by the owner)
func (*Chain) ContractAgentID ¶ added in v0.2.0
func (*Chain) DeployContract ¶
func (ch *Chain) DeployContract(keyPair *ed25519.KeyPair, name string, programHash hashing.HashValue, params ...interface{}) error
DeployContract deploys contract with the given name by its 'programHash'. 'sigScheme' represents the private key of the creator (nil defaults to chain originator). The 'creator' becomes an immutable property of the contract instance. The parameter 'programHash' can be one of the following:
- it is and ID of the blob stored on the chain in the format of Wasm binary
- it can be a hash (ID) of the example smart contract ("hardcoded"). The "hardcoded" smart contact must be made available with the call examples.AddProcessor
func (*Chain) DeployWasmContract ¶
func (ch *Chain) DeployWasmContract(keyPair *ed25519.KeyPair, name, fname string, params ...interface{}) error
DeployWasmContract is syntactic sugar for uploading Wasm binary from file and deploying the smart contract in one call
func (*Chain) DumpAccounts ¶
DumpAccounts dumps all account balances into the human readable string
func (*Chain) FindContract ¶
func (ch *Chain) FindContract(scName string) (*root.ContractRecord, error)
FindContract is a view call to the 'root' smart contract on the chain. It returns blobCache record of the deployed smart contract with the given name
func (*Chain) GetAccountBalance ¶
GetAccountBalance return all balances of colored tokens contained in the on-chain account controlled by the 'agentID'
func (*Chain) GetAccounts ¶
GetAccounts returns all accounts on the chain with non-zero balances
func (*Chain) GetAllowedStateControllerAddresses ¶ added in v0.2.0
func (ch *Chain) GetAllowedStateControllerAddresses() []ledgerstate.Address
AddAllowedStateController adds the address to the allowed state controlled address list
func (*Chain) GetBlobInfo ¶
GetBlobInfo return info about blob with the given hash with existence flag The blob information is returned as a map of pairs 'blobFieldName': 'fieldDataLength'
func (*Chain) GetBlockInfo ¶ added in v0.2.0
GetBlockInfo return BlockInfo for the particular block index in the chain
func (*Chain) GetChainOutput ¶ added in v0.2.0
func (ch *Chain) GetChainOutput() *ledgerstate.AliasOutput
func (*Chain) GetCommonAccountBalance ¶ added in v0.2.0
func (*Chain) GetCommonAccountIotas ¶ added in v0.2.0
func (*Chain) GetControlAddresses ¶ added in v0.2.0
func (ch *Chain) GetControlAddresses() *blocklog.ControlAddresses
func (*Chain) GetEventsForBlock ¶ added in v0.2.0
GetEventsForBlock calls the view in the 'blocklog' core smart contract to retrieve events for a given block.
func (*Chain) GetEventsForContract ¶ added in v0.2.0
GetEventsForContract calls the view in the 'blocklog' core smart contract to retrieve events for a given smart contract.
func (*Chain) GetEventsForRequest ¶ added in v0.2.0
GetEventsForRequest calls the view in the 'blocklog' core smart contract to retrieve events for a given request.
func (*Chain) GetFeeInfo ¶
GetFeeInfo returns the fee info for the specific chain and smart contract
- color of the fee tokens in the chain
- chain owner part of the fee (number of tokens)
- validator part of the fee (number of tokens)
Total fee is sum of owner fee and validator fee
func (*Chain) GetInfo ¶
GetInfo return main parameters of the chain:
- chainID
- agentID of the chain owner
- blobCache of contract deployed on the chain in the form of map 'contract hname': 'contract record'
func (*Chain) GetLatestBlockInfo ¶ added in v0.2.0
GetLatestBlockInfo return BlockInfo for the latest block in the chain
func (*Chain) GetOnChainLedger ¶ added in v0.2.0
func (*Chain) GetOnChainLedgerString ¶ added in v0.2.0
func (*Chain) GetRequestIDsForBlock ¶ added in v0.2.0
GetRequestIDsForBlock returns return the list of requestIDs settled in a particular block
func (*Chain) GetRequestReceipt ¶ added in v0.2.0
func (ch *Chain) GetRequestReceipt(reqID iscp.RequestID) (*blocklog.RequestReceipt, uint32, uint16, bool)
GetRequestReceipt gets the log records for a particular request, the block index and request index in the block
func (*Chain) GetRequestReceiptsForBlock ¶ added in v0.2.0
func (ch *Chain) GetRequestReceiptsForBlock(blockIndex uint32) []*blocklog.RequestReceipt
GetRequestReceiptsForBlock returns all request log records for a particular block
func (*Chain) GetRequestReceiptsForBlockRange ¶ added in v0.2.0
func (ch *Chain) GetRequestReceiptsForBlockRange(fromBlockIndex, toBlockIndex uint32) []*blocklog.RequestReceipt
GetRequestReceiptsForBlockRange returns all request log records for range of blocks, inclusively. Upper bound is 'latest block' is set to 0
func (*Chain) GetRequestReceiptsForBlockRangeAsStrings ¶ added in v0.2.0
func (*Chain) GetTotalAssets ¶
GetTotalAssets return total sum of colored tokens contained in the on-chain accounts
func (*Chain) GetTotalIotas ¶ added in v0.2.0
GetTotalIotas return total sum of iotas
func (*Chain) GetWasmBinary ¶
GetWasmBinary retrieves program binary in the format of Wasm blob from the chain by hash.
func (*Chain) GrantDeployPermission ¶
func (ch *Chain) GrantDeployPermission(keyPair *ed25519.KeyPair, deployerAgentID *iscp.AgentID) error
GrantDeployPermission gives permission to the specified agentID to deploy SCs into the chain
func (*Chain) IsRequestProcessed ¶ added in v0.2.0
IsRequestProcessed checks if the request is booked on the chain as processed
func (*Chain) MempoolInfo ¶ added in v0.2.0
func (ch *Chain) MempoolInfo() chain.MempoolInfo
MempoolInfo returns stats about the chain mempool
func (*Chain) PostRequestOffLedger ¶ added in v0.2.0
func (*Chain) PostRequestSync ¶
PostRequestSync posts a request synchronously sent by the test program to the smart contract on the same or another chain:
- creates a request transaction with the request block on it. The sigScheme is used to sign the inputs of the transaction or OriginatorKeyPair is used if parameter is nil
- adds request transaction to UTXODB
- runs the request in the VM. It results in new updated virtual state and a new transaction which anchors the state.
- adds the resulting transaction to UTXODB
- posts requests, contained in the resulting transaction to backlog queues of respective chains
- returns the result of the call to the smart contract's entry point
Note that in real network of Wasp nodes (the committee) posting the transaction is completely asynchronous, i.e. result of the call is not available to the originator of the post.
Unlike the real Wasp environment, the 'solo' environment makes PostRequestSync a synchronous call. It makes it possible step-by-step debug of the smart contract logic. The call should be used only from the main thread (goroutine)
func (*Chain) PostRequestSyncTx ¶
func (ch *Chain) PostRequestSyncTx(req *CallParams, keyPair *ed25519.KeyPair) (*ledgerstate.Transaction, dict.Dict, error)
func (*Chain) RemoveAllowedStateController ¶ added in v0.2.0
func (ch *Chain) RemoveAllowedStateController(addr ledgerstate.Address, keyPair *ed25519.KeyPair) error
AddAllowedStateController adds the address to the allowed state controlled address list
func (*Chain) RequestFromParamsToLedger ¶
func (ch *Chain) RequestFromParamsToLedger(req *CallParams, keyPair *ed25519.KeyPair) (*ledgerstate.Transaction, iscp.RequestID, error)
RequestFromParamsToLedger creates transaction with one request based on parameters and sigScheme Then it adds it to the ledger, atomically. Locking on the mutex is needed to prevent mess when several goroutines work on the same address
func (*Chain) RevokeDeployPermission ¶
func (ch *Chain) RevokeDeployPermission(keyPair *ed25519.KeyPair, deployerAgentID *iscp.AgentID) error
RevokeDeployPermission removes permission of the specified agentID to deploy SCs into the chain
func (*Chain) RotateStateController ¶ added in v0.2.0
func (ch *Chain) RotateStateController(newStateAddr ledgerstate.Address, newStateKeyPair, ownerKeyPair *ed25519.KeyPair) error
RotateStateController rotates the chain to the new controller address. We assume self-governed chain here. Mostly use for the testinng of committee rotation logic, otherwise not much needed for smart contract testing
func (*Chain) UploadBlob ¶
func (ch *Chain) UploadBlob(keyPair *ed25519.KeyPair, params ...interface{}) (ret hashing.HashValue, err error)
UploadBlob calls core 'blob' smart contract blob.FuncStoreBlob entry point to upload blob data to the chain. It returns hash of the blob, the unique identified of it. Takes request token and necessary fees from the 'sigScheme' address (or OriginatorAddress if nil).
The parameters must be either a dict.Dict, or a sequence of pairs 'fieldName': 'fieldValue'
func (*Chain) UploadBlobOptimized ¶
func (ch *Chain) UploadBlobOptimized(optimalSize int, keyPair *ed25519.KeyPair, params ...interface{}) (ret hashing.HashValue, err error)
UploadBlobOptimized does the same as UploadBlob, only better but more complicated It allows big data chunks to bypass the request transaction. Instead, in transaction only hash of the data is put. The data itself must be uploaded to the node (in this case into Solo environment), separately. Before running the request in VM, the hash references contained in the request transaction are resolved with the real data, previously uploaded directly.
func (*Chain) UploadWasm ¶
func (ch *Chain) UploadWasm(keyPair *ed25519.KeyPair, binaryCode []byte) (ret hashing.HashValue, err error)
UploadWasm is a syntactic sugar of the UploadBlob used to upload Wasm binary to the chain.
parameter 'binaryCode' is the binary of Wasm smart contract program
The blob for the Wasm binary used fixed field names which are statically known by the 'root' smart contract which is responsible for the deployment of contracts on the chain
func (*Chain) UploadWasmFromFile ¶
func (ch *Chain) UploadWasmFromFile(keyPair *ed25519.KeyPair, fileName string) (ret hashing.HashValue, err error)
UploadWasmFromFile is a syntactic sugar to upload file content as blob data to the chain
func (*Chain) WaitForRequestsThrough ¶ added in v0.2.0
WaitForRequestsThrough waits for the moment when counters for incoming requests and removed requests in the mempool of the chain both become equal to the specified number
type Solo ¶
type Solo struct { // instance of the test T TestContext // contains filtered or unexported fields }
Solo is a structure which contains global parameters of the test: one per test instance
func New ¶
func New(t TestContext, debug, printStackTrace bool, seedOpt ...*ed25519.Seed) *Solo
New creates an instance of the `solo` environment.
If solo is used for unit testing, 't' should be the *testing.T instance; otherwise it can be either nil or an instance created with NewTestContext.
'debug' parameter 'true' means logging level is 'debug', otherwise 'info' 'printStackTrace' controls printing stack trace in case of errors
func NewWithLogger ¶ added in v0.2.0
New creates an instance of the `solo` environment with the given logger.
If solo is used for unit testing, 't' should be the *testing.T instance; otherwise it can be either nil or an instance created with NewTestContext.
func (*Solo) AddToLedger ¶
func (env *Solo) AddToLedger(tx *ledgerstate.Transaction) error
AddToLedger adds (synchronously confirms) transaction to the UTXODB ledger. Return error if it is invalid or double spend
func (*Solo) AdvanceClockBy ¶
AdvanceClockBy advances logical clock by time step
func (*Solo) AdvanceClockTo ¶
AdvanceClockTo advances logical clock to the specific time moment in the (logical) future
func (*Solo) AssertAddressBalance ¶
AssertAddressBalance asserts the UTXODB address balance of specific color in the address
func (*Solo) AssertAddressIotas ¶ added in v0.2.0
func (env *Solo) AssertAddressIotas(addr ledgerstate.Address, expected uint64)
func (*Solo) ClockStep ¶
func (env *Solo) ClockStep()
ClockStep advances logical clock by time step set by SetTimeStep
func (*Solo) EnablePublisher ¶ added in v0.2.0
EnablePublisher enables Solo publisher
func (*Solo) EnqueueRequests ¶
func (env *Solo) EnqueueRequests(tx *ledgerstate.Transaction)
EnqueueRequests adds requests contained in the transaction to mempools of respective target chains
func (*Solo) GetAddressBalance ¶
GetAddressBalance returns number of tokens of given color contained in the given address on the UTXODB ledger
func (*Solo) GetAddressBalances ¶
func (env *Solo) GetAddressBalances(addr ledgerstate.Address) colored.Balances
GetAddressBalances returns all colored balances of the address contained in the UTXODB ledger
func (*Solo) LogicalTime ¶
LogicalTime return current logical clock time on the 'solo' instance
func (*Solo) MintTokens ¶
MintTokens mints specified amount of new colored tokens in the given wallet (signature scheme) Returns the color of minted tokens: the hash of the transaction
func (*Solo) NewChain ¶
func (env *Solo) NewChain(chainOriginator *ed25519.KeyPair, name string, validatorFeeTarget ...*iscp.AgentID) *Chain
NewChain deploys new chain instance.
If 'chainOriginator' is nil, new one is generated and solo.Saldo (=1337) iotas are loaded from the UTXODB faucet. If 'validatorFeeTarget' is skipped, it is assumed equal to OriginatorAgentID To deploy a chain instance the following steps are performed:
- chain signature scheme (private key), chain address and chain ID are created
- empty virtual state is initialized
- origin transaction is created by the originator and added to the UTXODB
- 'init' request transaction to the 'root' contract is created and added to UTXODB
- backlog processing threads (goroutines) are started
- VM processor cache is initialized
- 'init' request is run by the VM. The 'root' contracts deploys the rest of the core contracts: '_default', 'blocklog', 'blob', 'accounts' and 'eventlog',
Upon return, the chain is fully functional to process requests
func (*Solo) NewKeyPair ¶ added in v0.2.0
NewSignatureSchemeAndPubKey generates new ed25519 signature scheme Returns signature scheme interface and public key in binary form
func (*Solo) NewKeyPairWithFunds ¶ added in v0.2.0
NewSignatureSchemeWithFundsAndPubKey generates new ed25519 signature scheme and requests some tokens from the UTXODB faucet. The amount of tokens is equal to solo.Saldo (=1000000) iotas Returns signature scheme interface and public key in binary form
func (*Solo) NewSeedFromIndex ¶ added in v0.2.0
func (*Solo) PutBlobDataIntoRegistry ¶
func (*Solo) RequestsForChain ¶ added in v0.2.0
func (env *Solo) RequestsForChain(tx *ledgerstate.Transaction, chainID *iscp.ChainID) ([]iscp.Request, error)
RequestsForChain parses the transaction and returns all requests contained in it which have chainID as the target
func (*Solo) SetTimeStep ¶
SetTimeStep sets default time step for the 'solo' instance
func (*Solo) WaitPublisher ¶ added in v0.2.0
func (env *Solo) WaitPublisher()
WaitPublisher waits until all messages are published
func (*Solo) WithNativeContract ¶ added in v0.2.0
func (env *Solo) WithNativeContract(c *coreutil.ContractProcessor) *Solo
WithNativeContract registers a native contract so that it may be deployed
type TestContext ¶ added in v0.2.0
type TestContext interface { Name() string Errorf(format string, args ...interface{}) FailNow() Logf(format string, args ...interface{}) }
TestContext is a subset of the interface provided by *testing.T and require.TestingT It allows to use Solo outside of unit tests.
func NewTestContext ¶ added in v0.2.0
func NewTestContext(name string) TestContext