Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add perun types && fix: add marshal method for script group #225

Open
wants to merge 10 commits into
base: v2
Choose a base branch
from
24 changes: 24 additions & 0 deletions transaction/script_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package transaction

import (
"encoding/json"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/nervosnetwork/ckb-sdk-go/v2/types"
)
Expand Down Expand Up @@ -43,3 +44,26 @@ func (r *ScriptGroup) UnmarshalJSON(input []byte) error {
}
return nil
}

func (r *ScriptGroup) MarshalJSON() ([]byte, error) {
toHexutilArray := func(in []uint32) []hexutil.Uint {
out := make([]hexutil.Uint, len(in))
for i, data := range in {
out[i] = hexutil.Uint(data)
}
return out
}

jsonObj := struct {
Script *types.Script `json:"script"`
GroupType types.ScriptType `json:"group_type"`
InputIndices []hexutil.Uint `json:"input_indices"`
OutputIndices []hexutil.Uint `json:"output_indices"`
}{
Script: r.Script,
GroupType: r.GroupType,
InputIndices: toHexutilArray(r.InputIndices),
OutputIndices: toHexutilArray(r.OutputIndices),
}
return json.Marshal(jsonObj)
}
7 changes: 4 additions & 3 deletions transaction/signer_test/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import (
"encoding/json"
"errors"
"fmt"
"os"
"runtime/debug"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/nervosnetwork/ckb-sdk-go/v2/crypto/secp256k1"
Expand All @@ -13,9 +17,6 @@ import (
"github.com/nervosnetwork/ckb-sdk-go/v2/transaction/signer/omnilock"
"github.com/nervosnetwork/ckb-sdk-go/v2/types"
"github.com/stretchr/testify/assert"
"os"
"runtime/debug"
"testing"
)

func TestIsSingleSigMatched(t *testing.T) {
Expand Down
196 changes: 196 additions & 0 deletions types/molecule/offchain_type.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file generated?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was supposed to be generated.
Also do keep the generator header when committing generated codes
It should contains something like:

// Generated by Molecule 0.7.3
// Generated by Moleculec-Go 0.1.10

in the head of the generated file in order to reproduce the source. also the original xxx.mol file should also be contained @ravi0131

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply. As @code-monad mentioned, it is generated.

Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package molecule

import (
"bytes"
"errors"
"strconv"
"strings"
)

type OffChainParticipantBuilder struct {
pub_key SEC1EncodedPubKey
payment_script Script
unlock_script Script
}

func (s *OffChainParticipantBuilder) Build() OffChainParticipant {
b := new(bytes.Buffer)

totalSize := HeaderSizeUint * (3 + 1)
offsets := make([]uint32, 0, 3)

offsets = append(offsets, totalSize)
totalSize += uint32(len(s.pub_key.AsSlice()))
offsets = append(offsets, totalSize)
totalSize += uint32(len(s.payment_script.AsSlice()))
offsets = append(offsets, totalSize)
totalSize += uint32(len(s.unlock_script.AsSlice()))

b.Write(packNumber(Number(totalSize)))

for i := 0; i < len(offsets); i++ {
b.Write(packNumber(Number(offsets[i])))
}

b.Write(s.pub_key.AsSlice())
b.Write(s.payment_script.AsSlice())
b.Write(s.unlock_script.AsSlice())
return OffChainParticipant{inner: b.Bytes()}
}

func (s *OffChainParticipantBuilder) PubKey(v SEC1EncodedPubKey) *OffChainParticipantBuilder {
s.pub_key = v
return s
}

func (s *OffChainParticipantBuilder) PaymentScript(v Script) *OffChainParticipantBuilder {
s.payment_script = v
return s
}

func (s *OffChainParticipantBuilder) UnlockScript(v Script) *OffChainParticipantBuilder {
s.unlock_script = v
return s
}

func NewOffChainParticipantBuilder() *OffChainParticipantBuilder {
return &OffChainParticipantBuilder{pub_key: SEC1EncodedPubKeyDefault(), payment_script: ScriptDefault(), unlock_script: ScriptDefault()}
}

type OffChainParticipant struct {
inner []byte
}

func OffChainParticipantFromSliceUnchecked(slice []byte) *OffChainParticipant {
return &OffChainParticipant{inner: slice}
}
func (s *OffChainParticipant) AsSlice() []byte {
return s.inner
}

func OffChainParticipantDefault() OffChainParticipant {
return *OffChainParticipantFromSliceUnchecked([]byte{155, 0, 0, 0, 16, 0, 0, 0, 49, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 16, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
}

func OffChainParticipantFromSlice(slice []byte, compatible bool) (*OffChainParticipant, error) {
sliceLen := len(slice)
if uint32(sliceLen) < HeaderSizeUint {
errMsg := strings.Join([]string{"HeaderIsBroken", "OffChainParticipant", strconv.Itoa(int(sliceLen)), "<", strconv.Itoa(int(HeaderSizeUint))}, " ")
return nil, errors.New(errMsg)
}

totalSize := unpackNumber(slice)
if Number(sliceLen) != totalSize {
errMsg := strings.Join([]string{"TotalSizeNotMatch", "OffChainParticipant", strconv.Itoa(int(sliceLen)), "!=", strconv.Itoa(int(totalSize))}, " ")
return nil, errors.New(errMsg)
}

if uint32(sliceLen) < HeaderSizeUint*2 {
errMsg := strings.Join([]string{"TotalSizeNotMatch", "OffChainParticipant", strconv.Itoa(int(sliceLen)), "<", strconv.Itoa(int(HeaderSizeUint * 2))}, " ")
return nil, errors.New(errMsg)
}

offsetFirst := unpackNumber(slice[HeaderSizeUint:])
if uint32(offsetFirst)%HeaderSizeUint != 0 || uint32(offsetFirst) < HeaderSizeUint*2 {
errMsg := strings.Join([]string{"OffsetsNotMatch", "OffChainParticipant", strconv.Itoa(int(offsetFirst % 4)), "!= 0", strconv.Itoa(int(offsetFirst)), "<", strconv.Itoa(int(HeaderSizeUint * 2))}, " ")
return nil, errors.New(errMsg)
}

if sliceLen < int(offsetFirst) {
errMsg := strings.Join([]string{"HeaderIsBroken", "OffChainParticipant", strconv.Itoa(int(sliceLen)), "<", strconv.Itoa(int(offsetFirst))}, " ")
return nil, errors.New(errMsg)
}

fieldCount := uint32(offsetFirst)/HeaderSizeUint - 1
if fieldCount < 3 {
return nil, errors.New("FieldCountNotMatch")
} else if !compatible && fieldCount > 3 {
return nil, errors.New("FieldCountNotMatch")
}

offsets := make([]uint32, fieldCount)

for i := 0; i < int(fieldCount); i++ {
offsets[i] = uint32(unpackNumber(slice[HeaderSizeUint:][int(HeaderSizeUint)*i:]))
}
offsets = append(offsets, uint32(totalSize))

for i := 0; i < len(offsets); i++ {
if i&1 != 0 && offsets[i-1] > offsets[i] {
return nil, errors.New("OffsetsNotMatch")
}
}

var err error

_, err = SEC1EncodedPubKeyFromSlice(slice[offsets[0]:offsets[1]], compatible)
if err != nil {
return nil, err
}

_, err = ScriptFromSlice(slice[offsets[1]:offsets[2]], compatible)
if err != nil {
return nil, err
}

_, err = ScriptFromSlice(slice[offsets[2]:offsets[3]], compatible)
if err != nil {
return nil, err
}

return &OffChainParticipant{inner: slice}, nil
}

func (s *OffChainParticipant) TotalSize() uint {
return uint(unpackNumber(s.inner))
}
func (s *OffChainParticipant) FieldCount() uint {
var number uint = 0
if uint32(s.TotalSize()) == HeaderSizeUint {
return number
}
number = uint(unpackNumber(s.inner[HeaderSizeUint:]))/4 - 1
return number
}
func (s *OffChainParticipant) Len() uint {
return s.FieldCount()
}
func (s *OffChainParticipant) IsEmpty() bool {
return s.Len() == 0
}
func (s *OffChainParticipant) CountExtraFields() uint {
return s.FieldCount() - 3
}

func (s *OffChainParticipant) HasExtraFields() bool {
return 3 != s.FieldCount()
}

func (s *OffChainParticipant) PubKey() *SEC1EncodedPubKey {
start := unpackNumber(s.inner[4:])
end := unpackNumber(s.inner[8:])
return SEC1EncodedPubKeyFromSliceUnchecked(s.inner[start:end])
}

func (s *OffChainParticipant) PaymentScript() *Script {
start := unpackNumber(s.inner[8:])
end := unpackNumber(s.inner[12:])
return ScriptFromSliceUnchecked(s.inner[start:end])
}

func (s *OffChainParticipant) UnlockScript() *Script {
var ret *Script
start := unpackNumber(s.inner[12:])
if s.HasExtraFields() {
end := unpackNumber(s.inner[16:])
ret = ScriptFromSliceUnchecked(s.inner[start:end])
} else {
ret = ScriptFromSliceUnchecked(s.inner[start:])
}
return ret
}

func (s *OffChainParticipant) AsBuilder() OffChainParticipantBuilder {
ret := NewOffChainParticipantBuilder().PubKey(*s.PubKey()).PaymentScript(*s.PaymentScript()).UnlockScript(*s.UnlockScript())
return *ret
}
Loading