signer

package
v2.3.0 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2024 License: MIT Imports: 13 Imported by: 1

Documentation

Overview

Package signer implements a CKB transaction signing framework.

It adopts an extension mechanism that new script can implement ScriptSigner and register the signing logic via TransactionSigner.RegisterSigner.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAnyCanPayMatched

func IsAnyCanPayMatched(key *secp256k1.Secp256k1Key, scriptArgs []byte) (bool, error)

func IsMultiSigMatched

func IsMultiSigMatched(key *secp256k1.Secp256k1Key, config *systemscript.MultisigConfig, scriptArgs []byte) (bool, error)

func IsPWLockMatched

func IsPWLockMatched(key *secp256k1.Secp256k1Key, scriptArgs []byte) bool

func IsSingleSigMatched

func IsSingleSigMatched(key *secp256k1.Secp256k1Key, scriptArgs []byte) (bool, error)

func MultiSignTransaction

func MultiSignTransaction(tx *types.Transaction, group []int, key *secp256k1.Secp256k1Key, config *systemscript.MultisigConfig) (bool, error)

func PWLockSignTransaction

func PWLockSignTransaction(tx *types.Transaction, group *transaction.ScriptGroup, key *secp256k1.Secp256k1Key) (bool, error)

func SignTransaction added in v2.0.3

func SignTransaction(tx *types.Transaction, group []int, witnessPlaceholder []byte, key crypto.Key) ([]byte, error)

SignTransaction signs transaction with index group and witness placeholder in secp256k1_blake160_sighash_all way

Types

type AnyCanPaySigner

type AnyCanPaySigner struct {
}

func (*AnyCanPaySigner) SignTransaction

func (s *AnyCanPaySigner) SignTransaction(tx *types.Transaction, group *transaction.ScriptGroup, ctx *transaction.Context) (bool, error)

type OmnilockConfiguration added in v2.0.3

type OmnilockConfiguration struct {
	Args             *omnilock.OmnilockArgs
	Mode             OmnilockMode
	MultisigConfig   *systemscript.MultisigConfig
	AdminListCell    *types.CellDep
	OmnilockIdentity *omnilock.OmnilockIdentity
}

type OmnilockMode added in v2.0.3

type OmnilockMode uint
const (
	OmnolockModeAuth          OmnilockMode = 0
	OmnolockModeAdministrator OmnilockMode = 1
)

type OmnilockSigner added in v2.0.3

type OmnilockSigner struct {
}

func (*OmnilockSigner) SignTransaction added in v2.0.3

func (s *OmnilockSigner) SignTransaction(transaction *types.Transaction, group *transaction.ScriptGroup, ctx *transaction.Context) (bool, error)

type PWLockSigner

type PWLockSigner struct {
}

func (*PWLockSigner) SignTransaction

func (s *PWLockSigner) SignTransaction(transaction *types.Transaction, group *transaction.ScriptGroup, ctx *transaction.Context) (bool, error)

type ScriptSigner

type ScriptSigner interface {
	SignTransaction(transaction *types.Transaction, group *transaction.ScriptGroup, ctx *transaction.Context) (bool, error)
}

The interface ScriptSigner is for scripts to register their signing logic.

The function SignTransaction is the callback called by TransactionSigner on matched ScriptSigners, for each context passed in TransactionSigner.SignTransaction.

The transaction.Context provides extra data for the signer. For example, Secp256k1Blake160SighashAllSigner.SignTransaction requires user to pass the private keys as contexts.

Returns bool indicating whether the transaction has been modified.

Example

This example demonstrates how to use a custom script CapacityDiff (https://github.com/doitian/ckb-sdk-examples-capacity-diff).

CapacityDiff verifies the witness matches the capacity difference.

  • The script loads the witness for the first input in the script group using the WitnessArgs layout.
  • The total input capacity is the sum of all the input cells in the script group.
  • The total output capacity is the sum of all the output cells having the same lock script as the script group.
  • The capacity difference is a 64-bit signed integer which equals to total output capacity minus total input capacity.
  • The witness is encoded using two's complement and little endian.
package main

import (
	"context"
	"encoding/binary"
	"reflect"

	"github.com/nervosnetwork/ckb-sdk-go/v2/rpc"
	"github.com/nervosnetwork/ckb-sdk-go/v2/transaction"
	"github.com/nervosnetwork/ckb-sdk-go/v2/transaction/signer"
	"github.com/nervosnetwork/ckb-sdk-go/v2/types"
)

type CapacityDiffContext struct {
	rpc rpc.Client
	ctx context.Context
}

func (ctx CapacityDiffContext) getInputCell(outPoint *types.OutPoint) (*types.CellOutput, error) {
	cellWithStatus, err := ctx.rpc.GetLiveCell(ctx.ctx, outPoint, false, nil)
	if err != nil {
		return nil, err
	}

	return cellWithStatus.Cell.Output, nil
}

type CapacityDiffScriptSigner struct{}

func (s *CapacityDiffScriptSigner) SignTransaction(tx *types.Transaction, group *transaction.ScriptGroup, ctx *transaction.Context) (bool, error) {
	scriptContext, ok := ctx.Payload.(CapacityDiffContext)
	if !ok {
		return false, nil
	}

	total := int64(0)
	for _, i := range group.InputIndices {
		inputCell, err := scriptContext.getInputCell(tx.Inputs[i].PreviousOutput)
		if err != nil {
			return false, nil
		}
		total -= int64(inputCell.Capacity)
	}
	for _, output := range tx.Outputs {
		if reflect.DeepEqual(output.Lock, group.Script) {
			total += int64(output.Capacity)
		}
	}

	// The specification https://go.dev/ref/spec#Numeric_types says integres in
	// Go are repsented using two's complementation. So we can just cast it to
	// uin64 and get the little endian bytes.
	witness := make([]byte, 8)
	binary.LittleEndian.PutUint64(witness, uint64(total))

	witnessIndex := group.InputIndices[0]
	witnessArgs, err := types.DeserializeWitnessArgs(tx.Witnesses[witnessIndex])
	if err != nil {
		return false, err
	}
	witnessArgs.Lock = witness
	tx.Witnesses[witnessIndex] = witnessArgs.Serialize()

	return true, nil
}

// This example demonstrates how to use a custom script CapacityDiff
// (https://github.com/doitian/ckb-sdk-examples-capacity-diff).
//
// CapacityDiff verifies the witness matches the capacity difference.
//
//   - The script loads the witness for the first input in the script group using the WitnessArgs layout.
//   - The total input capacity is the sum of all the input cells in the script group.
//   - The total output capacity is the sum of all the output cells having the same lock script as the script group.
//   - The capacity difference is a 64-bit signed integer which equals to total output capacity minus total input capacity.
//   - The witness is encoded using two's complement and little endian.
func main() {
	signer := signer.NewTransactionSigner()
	signer.RegisterSigner(
		types.HexToHash("0x6283a479a3cf5d4276cd93594de9f1827ab9b55c7b05b3d28e4c2e0a696cfefd"),
		types.ScriptTypeType,
		&CapacityDiffScriptSigner{},
	)
}
Output:

type Secp256k1Blake160MultisigAllSigner

type Secp256k1Blake160MultisigAllSigner struct {
}

func (*Secp256k1Blake160MultisigAllSigner) SignTransaction

func (s *Secp256k1Blake160MultisigAllSigner) SignTransaction(transaction *types.Transaction, group *transaction.ScriptGroup, ctx *transaction.Context) (bool, error)

type Secp256k1Blake160SighashAllSigner

type Secp256k1Blake160SighashAllSigner struct {
}

func (*Secp256k1Blake160SighashAllSigner) SignTransaction

type TransactionSigner

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

func GetTransactionSignerInstance

func GetTransactionSignerInstance(network types.Network) *TransactionSigner

func NewTransactionSigner

func NewTransactionSigner() *TransactionSigner

func (*TransactionSigner) RegisterLockSigner

func (r *TransactionSigner) RegisterLockSigner(codeHash types.Hash, signer ScriptSigner)

func (*TransactionSigner) RegisterSigner

func (r *TransactionSigner) RegisterSigner(codeHash types.Hash, scriptType types.ScriptType, signer ScriptSigner)

func (*TransactionSigner) RegisterTypeSigner

func (r *TransactionSigner) RegisterTypeSigner(codeHash types.Hash, signer ScriptSigner)

func (*TransactionSigner) SignTransaction

func (r *TransactionSigner) SignTransaction(tx *transaction.TransactionWithScriptGroups, contexts ...*transaction.Context) ([]int, error)

func (*TransactionSigner) SignTransactionByPrivateKeys

func (r *TransactionSigner) SignTransactionByPrivateKeys(tx *transaction.TransactionWithScriptGroups, privKeys ...string) ([]int, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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