Documentation ¶
Overview ¶
Package smartcontract contains functions to deal with widely used scripts and NEP-14 Parameters. Neo is all about various executed code, verifications and executions of transactions need NeoVM code and this package simplifies creating it for common tasks like multisignature verification scripts or transaction entry scripts that call previously deployed contracts. Another problem related to scripts and invocations is that RPC invocations use JSONized NEP-14 parameters, so this package provides types and methods to deal with that too.
Index ¶
- Constants
- func CreateCallAndPrefetchIteratorScript(contract util.Uint160, operation string, maxIteratorResultItems int, ...) ([]byte, error)
- func CreateCallAndUnwrapIteratorScript(contract util.Uint160, operation string, maxIteratorResultItems int, ...) ([]byte, error)
- func CreateCallScript(contract util.Uint160, method string, params ...any) ([]byte, error)
- func CreateCallWithAssertScript(contract util.Uint160, method string, params ...any) ([]byte, error)
- func CreateDefaultMultiSigRedeemScript(publicKeys keys.PublicKeys) ([]byte, error)
- func CreateMajorityMultiSigRedeemScript(publicKeys keys.PublicKeys) ([]byte, error)
- func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, error)
- func ExpandParameterToEmitable(param Parameter) (any, error)
- func GetDefaultHonestNodeCount(n int) int
- func GetMajorityHonestNodeCount(n int) int
- type Builder
- type Convertible
- type ParamType
- func (pt ParamType) ConvertToStackitemType() stackitem.Type
- func (pt *ParamType) DecodeBinary(r *io.BinReader)
- func (pt ParamType) EncodeBinary(w *io.BinWriter)
- func (pt ParamType) EncodeDefaultValue(w *io.BinWriter)
- func (pt ParamType) MarshalJSON() ([]byte, error)
- func (pt ParamType) MarshalYAML() (any, error)
- func (pt ParamType) Match(v stackitem.Item) bool
- func (pt ParamType) String() string
- func (pt *ParamType) UnmarshalJSON(data []byte) error
- func (pt *ParamType) UnmarshalYAML(unmarshal func(any) error) error
- type Parameter
- type ParameterPair
Examples ¶
Constants ¶
const ( Hash160Len = util.Uint160Size Hash256Len = util.Uint256Size PublicKeyLen = 33 SignatureLen = keys.SignatureLen )
Lengths (in bytes) of fixed-size types.
Variables ¶
This section is empty.
Functions ¶
func CreateCallAndPrefetchIteratorScript ¶
func CreateCallAndPrefetchIteratorScript(contract util.Uint160, operation string, maxIteratorResultItems int, params ...any) ([]byte, error)
CreateCallAndPrefetchIteratorScript creates a script that calls 'operation' method of the 'contract' with the specified arguments. This method is expected to return an array of the first iterator items (up to maxIteratorResultItems, which cannot exceed VM limits) and, optionally, an iterator that then is traversed (using iterator.Next). The result of the script is an array containing extracted value elements and an iterator, if it can contain more items. If the iterator is present, it lies on top of the stack. Note, however, that if an iterator is returned, the number of remaining items can still be 0. This script should only be used for interactions with RPC server that have iterator sessions enabled.
func CreateCallAndUnwrapIteratorScript ¶
func CreateCallAndUnwrapIteratorScript(contract util.Uint160, operation string, maxIteratorResultItems int, params ...any) ([]byte, error)
CreateCallAndUnwrapIteratorScript creates a script that calls 'operation' method of the 'contract' with the specified arguments. This method is expected to return an iterator that then is traversed (using iterator.Next) with values (iterator.Value) extracted and added into array. At most maxIteratorResultItems number of items is processed this way (and this number can't exceed VM limits), the result of the script is an array containing extracted value elements. This script can be useful for interactions with RPC server that have iterator sessions disabled.
func CreateCallScript ¶
CreateCallScript returns a script that calls contract's method with the specified parameters. Whatever this method returns remains on the stack. See also (*Builder).InvokeMethod.
func CreateCallWithAssertScript ¶
func CreateCallWithAssertScript(contract util.Uint160, method string, params ...any) ([]byte, error)
CreateCallWithAssertScript returns a script that calls contract's method with the specified parameters expecting a Boolean value to be return that then is used for ASSERT. See also (*Builder).InvokeWithAssert.
func CreateDefaultMultiSigRedeemScript ¶
func CreateDefaultMultiSigRedeemScript(publicKeys keys.PublicKeys) ([]byte, error)
CreateDefaultMultiSigRedeemScript creates an "m out of n" type verification script using publicKeys length with the default BFT assumptions of (n - (n-1)/3) for m.
func CreateMajorityMultiSigRedeemScript ¶
func CreateMajorityMultiSigRedeemScript(publicKeys keys.PublicKeys) ([]byte, error)
CreateMajorityMultiSigRedeemScript creates an "m out of n" type verification script using publicKeys length with m set to majority.
func CreateMultiSigRedeemScript ¶
func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, error)
CreateMultiSigRedeemScript creates an "m out of n" type verification script where n is the length of publicKeys.
func ExpandParameterToEmitable ¶
ExpandParameterToEmitable converts a parameter to a type which can be handled as an array item by emit.Array. It correlates with the way an RPC server handles FuncParams for invoke* calls inside the request.ExpandArrayIntoScript function.
func GetDefaultHonestNodeCount ¶
GetDefaultHonestNodeCount returns minimum number of honest nodes required for network of size n.
func GetMajorityHonestNodeCount ¶
GetMajorityHonestNodeCount returns minimum number of honest nodes required for majority-style agreement.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder is used to create arbitrary scripts from the set of methods it provides. Each method emits some set of opcodes performing an action and (in most cases) returning a result. These chunks of code can be composed together to perform several actions in the same script (and therefore in the same transaction), but the end result (in terms of state changes and/or resulting items) of the script totally depends on what it contains and that's the responsibility of the Builder user. Builder is mostly used to create transaction scripts (also known as "entry scripts"), so the set of methods it exposes is tailored to this model of use and any calls emitted don't limit flags in any way (always use callflag.All).
When using this API keep in mind that the resulting script can't be larger than 64K (transaction.MaxScriptLength) to be used as a transaction entry script and it can't have more than 2048 elements on the stack. Technically, this limits the number of calls that can be made to a lesser value because invocations use the same stack too (the exact number depends on methods and parameters).
This API is not (and won't be) suitable to create complex scripts that use returned values as parameters to other calls or perform loops or do any other things that can be done in NeoVM. This hardly can be expressed in an API like this, so if you need more than that and if you're ready to work with bare NeoVM instructions please refer to emit and opcode packages.
Example ¶
package main import ( "context" "encoding/hex" "github.com/epicchainlabs/epicchain-go/pkg/rpcclient" "github.com/epicchainlabs/epicchain-go/pkg/rpcclient/actor" "github.com/epicchainlabs/epicchain-go/pkg/rpcclient/gas" "github.com/epicchainlabs/epicchain-go/pkg/rpcclient/neo" "github.com/epicchainlabs/epicchain-go/pkg/smartcontract" "github.com/epicchainlabs/epicchain-go/pkg/util" "github.com/epicchainlabs/epicchain-go/pkg/wallet" ) func main() { // No error checking done at all, intentionally. w, _ := wallet.NewWalletFromFile("somewhere") defer w.Close() c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{}) // Assuming there is one Account inside. a, _ := actor.NewSimple(c, w.Accounts[0]) pKey, _ := hex.DecodeString("03d9e8b16bd9b22d3345d6d4cde31be1c3e1d161532e3d0ccecb95ece2eb58336e") // Public key. b := smartcontract.NewBuilder() // Transfer + vote in a single script with each action leaving return value on the stack. b.InvokeMethod(neo.Hash, "transfer", a.Sender(), util.Uint160{0xff}, 1, nil) b.InvokeMethod(neo.Hash, "vote", pKey) script, _ := b.Script() // Actor has an Invoker inside, so we can perform test invocation using the script. res, _ := a.Run(script) if res.State != "HALT" || len(res.Stack) != 2 { panic("failed") // The script failed completely or didn't return proper number of return values. } transferResult, _ := res.Stack[0].TryBool() voteResult, _ := res.Stack[1].TryBool() if !transferResult { panic("transfer failed") } if !voteResult { panic("vote failed") } b.Reset() // Copy the old script above if you need it! // Multiple transfers of different tokens in a single script. If any of // them fails whole script fails. b.InvokeWithAssert(neo.Hash, "transfer", a.Sender(), util.Uint160{0x70}, 1, nil) b.InvokeWithAssert(gas.Hash, "transfer", a.Sender(), util.Uint160{0x71}, 100000, []byte("data")) b.InvokeWithAssert(neo.Hash, "transfer", a.Sender(), util.Uint160{0x72}, 1, nil) script, _ = b.Script() // Now send a transaction with this script via an RPC node. txid, vub, _ := a.SendRun(script) _ = txid _ = vub }
Output:
func (*Builder) Assert ¶
func (b *Builder) Assert()
Assert emits an ASSERT opcode that expects a Boolean value to be on the stack, checks if it's true and aborts the transaction if it's not.
func (*Builder) InvokeMethod ¶
InvokeMethod is the most generic contract method invoker, the code it produces packs all of the arguments given into an array and calls some method of the contract. It accepts as parameters everything that emit.Array accepts. The correctness of this invocation (number and type of parameters) is out of scope of this method, as well as return value, if contract's method returns something this value just remains on the execution stack.
func (*Builder) InvokeWithAssert ¶
InvokeWithAssert emits an invocation of the method (see InvokeMethod) with an ASSERT after the invocation. The presumption is that the method called returns a Boolean value signalling the success or failure of the operation. This pattern is pretty common, NEP-11 or NEP-17 'transfer' methods do exactly that as well as NEO's 'vote'. The ASSERT then allow to simplify transaction status checking, if action is successful then transaction is successful as well, if it went wrong than whole transaction fails (ends with vmstate.FAULT).
func (*Builder) Len ¶
Len returns the current length of the script. It's useful to perform script length checks (wrt transaction.MaxScriptLength limit) while building the script.
type Convertible ¶
Convertible is something that can be converted to Parameter.
type ParamType ¶
type ParamType int
ParamType represents the Type of the smart contract parameter.
const ( UnknownType ParamType = -1 AnyType ParamType = 0x00 BoolType ParamType = 0x10 IntegerType ParamType = 0x11 ByteArrayType ParamType = 0x12 StringType ParamType = 0x13 Hash160Type ParamType = 0x14 Hash256Type ParamType = 0x15 PublicKeyType ParamType = 0x16 SignatureType ParamType = 0x17 ArrayType ParamType = 0x20 MapType ParamType = 0x22 InteropInterfaceType ParamType = 0x30 VoidType ParamType = 0xff )
A list of supported smart contract parameter types.
func ConvertToParamType ¶
ConvertToParamType converts the provided value to the parameter type if it's a valid type.
func ParseParamType ¶
ParseParamType is a user-friendly string to ParamType converter, it's case-insensitive and makes the following conversions:
signature -> SignatureType bool, boolean -> BoolType int, integer -> IntegerType hash160 -> Hash160Type hash256 -> Hash256Type bytes, bytearray, filebytes -> ByteArrayType key, publickey -> PublicKeyType string -> StringType array, struct -> ArrayType map -> MapType interopinterface -> InteropInterfaceType void -> VoidType
anything else generates an error.
func (ParamType) ConvertToStackitemType ¶
ConvertToStackitemType converts ParamType to corresponding Stackitem.Type.
func (*ParamType) DecodeBinary ¶
DecodeBinary implements the io.Serializable interface.
func (ParamType) EncodeBinary ¶
EncodeBinary implements the io.Serializable interface.
func (ParamType) EncodeDefaultValue ¶
EncodeDefaultValue writes a script to push the default parameter value onto the evaluation stack into the given writer. It's mostly useful for constructing dummy invocation scripts when parameter types are known, but they can't be filled in. A best effort approach is used, it can't be perfect since for many types the exact values can be arbitrarily long, but it tries to do something reasonable in each case. For signatures, strings, arrays and "any" type a 64-byte zero-filled value is used, hash160 and hash256 use appropriately sized values, public key is represented by 33-byte value while 32 bytes are used for integer and a simple push+convert is used for boolean. Other types produce no code at all.
func (ParamType) MarshalJSON ¶
MarshalJSON implements the json.Marshaler interface.
func (ParamType) MarshalYAML ¶
MarshalYAML implements the YAML Marshaler interface.
func (*ParamType) UnmarshalJSON ¶
UnmarshalJSON implements the json.Unmarshaler interface.
type Parameter ¶
type Parameter struct { // Type of the parameter. Type ParamType `json:"type"` // The actual value of the parameter. Value any `json:"value"` }
Parameter represents a smart contract parameter.
func NewParameter ¶
NewParameter returns a Parameter with a proper initialized Value of the given ParamType.
func NewParameterFromString ¶
NewParameterFromString returns a new Parameter initialized from the given string in neo-go-specific format. It is intended to be used in user-facing interfaces and has some heuristics in it to simplify parameter passing. The exact syntax is documented in the cli documentation.
func NewParameterFromValue ¶
NewParameterFromValue infers Parameter type from the value given and adjusts the value if needed. It does not copy the value if it can avoid doing so. All regular integers, util.*, keys.PublicKey*, string and bool types are supported, slice of byte slices is accepted and converted as well.
func NewParametersFromValues ¶
NewParametersFromValues is similar to NewParameterFromValue except that it works with multiple values and returns a simple slice of Parameter.
func (Parameter) MarshalJSON ¶
MarshalJSON implements the Marshaler interface.
func (*Parameter) ToStackItem ¶
ToStackItem converts smartcontract parameter to stackitem.Item.
func (*Parameter) UnmarshalJSON ¶
UnmarshalJSON implements the Unmarshaler interface.
type ParameterPair ¶
ParameterPair represents a key-value pair, a slice of which is stored in MapType Parameter.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
standard
Package standard contains interfaces for well-defined standards and a function for checking if an arbitrary manifest complies with them.
|
Package standard contains interfaces for well-defined standards and a function for checking if an arbitrary manifest complies with them. |
Package zkpbinding contains a set of helper functions aimed to generate and interact with Verifier smart contract written in Go and using Groth-16 proving system over BLS12-381 elliptic curve to verify proofs.
|
Package zkpbinding contains a set of helper functions aimed to generate and interact with Verifier smart contract written in Go and using Groth-16 proving system over BLS12-381 elliptic curve to verify proofs. |