router

package
v0.10.5 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2022 License: MIT Imports: 10 Imported by: 29

README

Hyperledger Fabric chaincode kit (CCKit)

Chaincode methods router

To simplify chaincode development, we tried to compose common software development patterns, such as routing, middleware and invoke context:

  • Routing refers to determining how an application responds to a client request to a particular endpoint. Chaincode router uses rules about how to map chaincode invocation to particular handler, as well as what kind of middleware need to be used during request, for example how to convert incoming argument from []byte to target type (string, struct etc)

  • Invoke context is abstraction over ChaincodeStubInterface, represents the context of the current chaincode invocation. It holds request, response and client (Identity) reference, converted parameters, as well as state and log reference. As Context is an interface, it is easy to extend it with custom methods.

  • Middleware functions are functions that have access to the invoke context, invoke result and the next middleware function in the chaincode’s invoke-response cycle. The next middleware function is commonly denoted by a variable named next.

Middleware

Middleware functions can perform the following tasks:

  • Convert input args from byte slice to desired type
  • Check access control requirements
  • End the request-response cycle.
  • Call the next middleware function in the stack.

Defining chaincode function and their arguments

Delegating chaincode methods handling

router/context.go

// Chaincode default chaincode implementation with router
type Chaincode struct {
	router *Group
}


// Init initializes chain code - sets chaincode "owner"
func (cc *Chaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
	// delegate handling to router
	return cc.router.HandleInit(stub)
}

// Invoke - entry point for chain code invocations
func (cc *Chaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	// delegate handling to router
	return cc.router.Handle(stub)
}

Chaincode function and their arguments

Example from ERC20 chaincode:

func NewErc20FixedSupply() *router.Chaincode {
	r := router.New(`erc20fixedSupply`).Use(p.StrictKnown).

		// Chaincode init function, initiates token smart contract with token symbol, name and totalSupply
		Init(invokeInitFixedSupply, p.String(`symbol`), p.String(`name`), p.Int(`totalSupply`)).

		// Get token symbol
		Query(`symbol`, querySymbol).

		// Get token name
		Query(`name`, queryName).

		// Get the total token supply
		Query(`totalSupply`, queryTotalSupply).

		//  get account balance
		Query(`balanceOf`, queryBalanceOf, p.String(`mspId`), p.String(`certId`)).

		//Send value amount of tokens
		Invoke(`transfer`, invokeTransfer, p.String(`toMspId`), p.String(`toCertId`), p.Int(`amount`)).

		// Allow spender to withdraw from your account, multiple times, up to the _value amount.
		// If this function is called again it overwrites the current allowance with _valu
		Invoke(`approve`, invokeApprove, p.String(`spenderMspId`), p.String(`spenderCertId`), p.Int(`amount`)).

		//    Returns the amount which _spender is still allowed to withdraw from _owner]
		Invoke(`allowance`, queryAllowance, p.String(`ownerMspId`), p.String(`ownerCertId`),
			p.String(`spenderMspId`), p.String(`spenderCertId`)).

		// Send amount of tokens from owner account to another
		Invoke(`transferFrom`, invokeTransferFrom, p.String(`fromMspId`), p.String(`fromCertId`),
			p.String(`toMspId`), p.String(`toCertId`), p.Int(`amount`))

	return router.NewChaincode(r)
}

Documentation

Overview

Package router provides base router for using in chaincode Invoke function

Index

Constants

View Source
const DefaultParam = `default`

DefaultParam default parameter name

Variables

View Source
var (
	// ErrEmptyArgs occurs when trying to invoke chaincode method with empty args
	ErrEmptyArgs = errors.New(`empty args`)

	// ErrMethodNotFound occurs when trying to invoke non existent chaincode method
	ErrMethodNotFound = errors.New(`chaincode method not found`)

	// ErrArgsNumMismatch occurs when the number of declared and the number of arguments passed does not match
	ErrArgsNumMismatch = errors.New(`chaincode method args count mismatch`)

	// ErrHandlerError error in handler
	ErrHandlerError = errors.New(`router handler error`)
)
View Source
var ErrInvalidRequest = errors.New(`invalid request`)

Functions

func EmptyContextHandler added in v0.3.0

func EmptyContextHandler(c Context) (interface{}, error)

func NewContext added in v0.6.1

func NewContext(stub shim.ChaincodeStubInterface, logger *zap.Logger) *context

NewContext creates new instance of router.Context

func NewLogger added in v0.6.1

func NewLogger(name string) *zap.Logger

NewLogger creates new instance of shim.ChaincodeLogger

func ValidateRequest added in v0.7.8

func ValidateRequest(request Validator) error

ValidateRequest use Validator interface and create error, allow to use error.Is(ErrInvalidRequest)

Types

type Chaincode

type Chaincode struct {
	// contains filtered or unexported fields
}

Chaincode default chaincode implementation with router

func NewChaincode

func NewChaincode(r *Group) *Chaincode

NewChaincode new default chaincode implementation

func (*Chaincode) Init

======== Base methods ====================================

Init initializes chain code - sets chaincode "owner"

func (*Chaincode) Invoke

Invoke - entry point for chain code invocations

type Context

type Context interface {
	Clone() Context

	Stub() shim.ChaincodeStubInterface

	// Client returns invoker ClientIdentity
	Client() (cid.ClientIdentity, error)

	// Response returns response builder
	Response() Response
	Logger() *zap.Logger
	Path() string
	Handler() *HandlerMeta
	SetHandler(*HandlerMeta)
	State() state.State
	UseState(state.State) Context

	// Time returns txTimestamp
	Time() (time.Time, error)

	ReplaceArgs(args [][]byte) Context // replace args, for usage in preMiddleware
	GetArgs() [][]byte

	// Deprecated: Use Params instead.
	Args() InterfaceMap

	// Deprecated: Use Arg instead.
	Arg(string) interface{}

	// Deprecated: Use ParamString instead.
	ArgString(string) string

	// Deprecated: Use ParamBytes instead.
	ArgBytes(string) []byte

	// Deprecated: Use ParamInt instead.
	ArgInt(string) int

	// Deprecated: Use SetParam instead.
	SetArg(string, interface{})

	// Params returns parameter values.
	Params() InterfaceMap

	// Param returns parameter value.
	Param(name ...string) interface{}

	// ParamString returns parameter value as string.
	ParamString(name string) string

	// ParamBytes returns parameter value as bytes.
	ParamBytes(name string) []byte

	// ParamInt returns parameter value as int.
	ParamInt(name string) int

	// ParamInt32 returns parameter value as int32.
	ParamInt32(name string) int32

	// SetParam sets parameter value.
	SetParam(name string, value interface{})

	// Get retrieves data from the context.
	Get(key string) interface{}
	// Set saves data in the context.
	Set(key string, value interface{})

	// Deprecated: Use Event().Set() instead
	SetEvent(string, interface{}) error

	Event() state.Event
	UseEvent(state.Event) Context
}

Context of chaincode invoke

func ContextWithStateCache added in v0.7.4

func ContextWithStateCache(ctx Context) Context

type ContextHandlerFunc

type ContextHandlerFunc func(Context) peer.Response

ContextHandlerFunc use stub context as input parameter

type ContextMiddlewareFunc

type ContextMiddlewareFunc func(nextOrPrev ContextHandlerFunc, pos ...int) ContextHandlerFunc

ContextMiddlewareFunc middleware for ContextHandlerFun

type ContextResponse

type ContextResponse struct {
	// contains filtered or unexported fields
}

ContextResponse implementation

func (ContextResponse) Create

func (c ContextResponse) Create(data interface{}, err interface{}) peer.Response

Create returns error response if err != nil

func (ContextResponse) Error

func (c ContextResponse) Error(err interface{}) peer.Response

Error response

func (ContextResponse) Success

func (c ContextResponse) Success(data interface{}) peer.Response

Success response

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group of chain code functions

func New

func New(name string) *Group

New group of chain code functions

func (*Group) After added in v0.5.3

func (g *Group) After(middleware ...MiddlewareFunc) *Group

func (*Group) Context

func (g *Group) Context(stub shim.ChaincodeStubInterface) Context

Context returns chain code invoke context for provided path and stub

func (*Group) ContextHandler

func (g *Group) ContextHandler(path string, fn ContextHandlerFunc) *Group

ContextHandler adds new context handler using presented path

func (*Group) Group

func (g *Group) Group(path string) *Group

Group gets new group using presented path New group can be used as independent

func (*Group) Handle

func (g *Group) Handle(stub shim.ChaincodeStubInterface) peer.Response

Handle used for using in CC Invoke function Must be called after adding new routes using Add function

func (*Group) HandleInit

func (g *Group) HandleInit(stub shim.ChaincodeStubInterface) peer.Response

HandleInit handle chaincode init method

func (*Group) Init

func (g *Group) Init(handler HandlerFunc, middleware ...MiddlewareFunc) *Group

func (*Group) Invoke

func (g *Group) Invoke(path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Group

Invoke defines handler and middleware for invoke chaincode method (state change, need to send to orderer)

func (*Group) Pre

func (g *Group) Pre(middleware ...ContextMiddlewareFunc) *Group

func (*Group) Query

func (g *Group) Query(path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Group

Query defines handler and middleware for querying chaincode method (no state change, no send to orderer)

func (*Group) StubHandler

func (g *Group) StubHandler(path string, fn StubHandlerFunc) *Group

StubHandler adds new stub handler using presented path

func (*Group) Use

func (g *Group) Use(middleware ...MiddlewareFunc) *Group

Use middleware function in chain code functions group

type HandlerFunc

type HandlerFunc func(Context) (interface{}, error)

HandlerFunc returns result as interface and error, this is converted to peer.Response via response.Create

type HandlerMeta added in v0.5.3

type HandlerMeta struct {
	Hdl  HandlerFunc
	Type MethodType
}

type InterfaceMap

type InterfaceMap map[string]interface{}

InterfaceMap map of interfaces

type MethodType added in v0.5.3

type MethodType string
const (
	InitFunc                = `init`
	MethodInvoke MethodType = `invoke`
	MethodQuery  MethodType = `query`
)

type MiddlewareFunc

type MiddlewareFunc func(HandlerFunc, ...int) HandlerFunc

MiddlewareFunc middleware for HandlerFunc

type Response

type Response interface {
	Error(err interface{}) peer.Response
	Success(data interface{}) peer.Response
	Create(data interface{}, err interface{}) peer.Response
}

Response chaincode interface

type Router added in v0.5.3

type Router interface {
	HandleInit(shim.ChaincodeStubInterface)
	Handle(shim.ChaincodeStubInterface)
	Query(path string, handler HandlerFunc, middleware ...MiddlewareFunc) Router
	Invoke(path string, handler HandlerFunc, middleware ...MiddlewareFunc) Router
}

type StubHandlerFunc

type StubHandlerFunc func(shim.ChaincodeStubInterface) peer.Response

StubHandlerFunc acts as raw chaincode invoke method, accepts stub and returns peer.Response

type Validator added in v0.7.8

type Validator interface {
	Validate() error
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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