compiler

package
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 26, 2018 License: AGPL-3.0 Imports: 13 Imported by: 12

Documentation

Overview

Package equity provides a compiler for Chain's Equity contract language.

A contract is a means to lock some payment in the output of a transaction. It contains a number of clauses, each describing a way to unlock, or redeem, the payment in a subsequent transaction. By executing the statements in a clause, using contract arguments supplied by the payer and clause arguments supplied by the redeemer, nodes in a Chain network can determine whether a proposed spend is valid.

The language definition is in flux, but here's what's implemented as of late May 2017.

program = contract*

contract = "contract" identifier "(" [params] ")" "locks" identifier "{" clause+ "}"

  The identifier after "locks" is a name for the value locked by
  the contract. It must be unlocked or re-locked (with "unlock"
  or "lock") in every clause.

clause = "clause" identifier "(" [params] ")" ["requires" requirements] "{" statement+ "}"

  The requirements are blockchain values that must be present in
  the spending transaction in order to spend the value locked by
  the earlier transaction. Each such value must be re-locked
  (with "lock") in its clause.

statement = verify | unlock | lock

verify = "verify" expr

  Verifies that boolean expression expr produces a true result.

unlock = "unlock" expr

  Expr must evaluate to the contract value. This unlocks that
  value for any use.

lock = "lock" expr "with" expr

  The first expr must be a blockchain value (i.e., one named
  with "locks" or "requires"). The second expr must be a
  program. This unlocks expr and re-locks it with the new
  program.

requirements = requirement | requirements "," requirement

requirement = identifier ":" expr "of" expr

  The first expr must be an amount, the second must be an
  asset. This denotes that the named value must have the given
  quantity and asset type.

params = param | params "," param

param = idlist ":" identifier

  The identifiers in idlist are individual parameter names. The
  identifier after the colon is their type. Available types are:

    Amount; Asset; Boolean; Hash; Integer; Program; PublicKey;
    Signature; String; Time

idlist = identifier | idlist "," identifier

expr = unary_expr | binary_expr | call_expr | identifier | "(" expr ")" | literal

unary_expr = unary_op expr

binary_expr = expr binary_op expr

call_expr = expr "(" [args] ")"

  If expr is the name of an Equity contract, then calling it (with
  the appropriate arguments) produces a program suitable for use
  in "lock" statements.

  Otherwise, expr should be one of these builtin functions:

    sha3(x)
      SHA3-256 hash of x.
    sha256(x)
      SHA-256 hash of x.
    size(x)
      Size in bytes of x.
    abs(x)
      Absolute value of x.
    min(x, y)
      The lesser of x and y.
    max(x, y)
      The greater of x and y.
    checkTxSig(pubkey, signature)
      Whether signature matches both the spending
      transaction and pubkey.
    concat(x, y)
      The concatenation of x and y.
    concatpush(x, y)
      The concatenation of x with the bytecode sequence
      needed to push y on the ChainVM stack.
    before(x)
      Whether the spending transaction is happening before
      time x.
    after(x)
      Whether the spending transaction is happening after
      time x.
    checkTxMultiSig([pubkey1, pubkey2, ...], [sig1, sig2, ...])
      Like checkTxSig, but for M-of-N signature checks.
      Every sig must match both the spending transaction and
      one of the pubkeys. There may be more pubkeys than
      sigs, but they are only checked left-to-right so must
      be supplied in the same order as the sigs. The square
      brackets here are literal and must appear as shown.

unary_op = "-" | "~"

binary_op = ">" | "<" | ">=" | "<=" | "==" | "!=" | "^" | "|" |
      "+" | "-" | "&" | "<<" | ">>" | "%" | "*" | "/"

args = expr | args "," expr

literal = int_literal | str_literal | hex_literal

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Instantiate

func Instantiate(body []byte, params []*Param, recursive bool, args []ContractArg) ([]byte, error)

Types

type Clause

type Clause struct {
	// Name is the clause name.
	Name string `json:"name"`

	// Params is the list of clause parameters.
	Params []*Param `json:"params,omitempty"`

	// Reqs is the list of requirements (from the clause's "requires"
	// section).
	Reqs []*ClauseReq `json:"reqs,omitempty"`

	// BlockHeight is the list of expressions passed to greater()/less() in this
	// clause.
	BlockHeight []string `json:"blockheight,omitempty"`

	// HashCalls is the list of hash functions and their arguments used
	// in this clause.
	HashCalls []HashCall `json:"hash_calls,omitempty"`

	// Values is the list of values unlocked or relocked in this clause.
	Values []ValueInfo `json:"values"`

	// Contracts is the list of contracts called by this clause.
	Contracts []string `json:"contracts,omitempty"`
	// contains filtered or unexported fields
}

Clause is a compiled contract clause.

type ClauseReq

type ClauseReq struct {
	Name string `json:"name"`

	// Asset is the expression describing the required asset.
	Asset string `json:"asset"`

	// Amount is the expression describing the required amount.
	Amount string `json:"amount"`
	// contains filtered or unexported fields
}

ClauseReq describes a payment requirement of a clause (one of the things after the "requires" keyword).

type Contract

type Contract struct {
	// Name is the contract name.
	Name string `json:"name"`

	// Params is the list of contract parameters.
	Params []*Param `json:"params,omitempty"`

	// Clauses is the list of contract clauses.
	Clauses []*Clause `json:"clauses"`

	// Value is the name of the value locked by the contract.
	Value string `json:"value"`

	// Body is the optimized bytecode of the contract body. This is not
	// a complete program!  Use instantiate to turn this (plus some
	// arguments) into a program.
	Body chainjson.HexBytes `json:"body_bytecode"`

	// Opcodes is the human-readable string of opcodes corresponding to
	// Body.
	Opcodes string `json:"body_opcodes,omitempty"`

	// Recursive tells whether this contract calls itself.  (This is
	// used to select between two possible instantiation options.)
	Recursive bool `json:"recursive"`

	// Pre-optimized list of instruction steps, with stack snapshots.
	Steps []Step `json:"-"`
}

Contract is a compiled Equity contract.

func Compile

func Compile(r io.Reader) ([]*Contract, error)

Compile parses a sequence of Equity contracts from the supplied reader and produces Contract objects containing the compiled bytecode and other analysis. If argMap is non-nil, it maps contract names to lists of arguments with which to instantiate them as programs, with the results placed in the contract's Program field. A contract named in argMap but not found in the input is silently ignored.

type ContractArg

type ContractArg struct {
	B *bool               `json:"boolean,omitempty"`
	I *int64              `json:"integer,omitempty"`
	S *chainjson.HexBytes `json:"string,omitempty"`
}

ContractArg is an argument with which to instantiate a contract as a program. Exactly one of B, I, and S should be supplied.

func (*ContractArg) UnmarshalJSON

func (a *ContractArg) UnmarshalJSON(b []byte) error

type HashCall

type HashCall struct {
	// HashType is "sha3" or "sha256".
	HashType string `json:"hash_type"`

	// Arg is the expression passed to the hash function.
	Arg string `json:"arg"`

	// ArgType is the type of Arg.
	ArgType string `json:"arg_type"`
}

HashCall describes a call to a hash function.

type Param

type Param struct {
	// Name is the parameter name.
	Name string `json:"name"`

	// Type is the declared parameter type.
	Type typeDesc `json:"type"`

	// InferredType, if available, is a more-specific type than Type,
	// inferred from the logic of the contract.
	InferredType typeDesc `json:"inferred_type,omitempty"`
}

Param is a contract or clause parameter.

type Step

type Step struct {
	Opcodes string `json:"opcodes"`
	Stack   string `json:"stack"`
}

type ValueInfo

type ValueInfo struct {
	// Name is the clause's name for this value.
	Name string `json:"name"`

	// Program is the program expression used to the lock the value, if
	// the value is locked with "lock." If it's unlocked with "unlock"
	// instead, this is empty.
	Program string `json:"program,omitempty"`

	// Asset is the expression describing the asset type the value must
	// have, as it appears in a clause's "requires" section. If this is
	// the contract value instead, this is empty.
	Asset string `json:"asset,omitempty"`

	// Amount is the expression describing the amount the value must
	// have, as it appears in a clause's "requires" section. If this is
	// the contract value instead, this is empty.
	Amount string `json:"amount,omitempty"`
}

ValueInfo describes how a blockchain value is used in a contract clause.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL