Merge pull request #74 from filecoin-project/feat/payment-channels
implement initial payment channel actor
This commit is contained in:
commit
663cdbe167
@ -87,7 +87,7 @@ type FullNode interface {
|
||||
WalletNew(context.Context, string) (address.Address, error)
|
||||
WalletList(context.Context) ([]address.Address, error)
|
||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||||
WalletSign(context.Context, address.Address, []byte) (*chain.Signature, error)
|
||||
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
|
||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||
|
||||
// Really not sure where this belongs. It could go on the wallet, or the message pool, or the chain...
|
||||
|
@ -49,7 +49,7 @@ type FullNodeStruct struct {
|
||||
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||
WalletSign func(context.Context, address.Address, []byte) (*chain.Signature, error) `perm:"sign"`
|
||||
WalletSign func(context.Context, address.Address, []byte) (*types.Signature, error) `perm:"sign"`
|
||||
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
|
||||
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
|
||||
|
||||
@ -147,7 +147,7 @@ func (c *FullNodeStruct) WalletBalance(ctx context.Context, a address.Address) (
|
||||
return c.Internal.WalletBalance(ctx, a)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletSign(ctx context.Context, k address.Address, msg []byte) (*chain.Signature, error) {
|
||||
func (c *FullNodeStruct) WalletSign(ctx context.Context, k address.Address, msg []byte) (*types.Signature, error) {
|
||||
return c.Internal.WalletSign(ctx, k, msg)
|
||||
}
|
||||
|
||||
|
281
chain/actors/actor_paych.go
Normal file
281
chain/actors/actor_paych.go
Normal file
@ -0,0 +1,281 @@
|
||||
package actors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
)
|
||||
|
||||
const ChannelClosingDelay = 6 * 60 * 2 // six hours
|
||||
|
||||
func init() {
|
||||
cbor.RegisterCborType(PaymentChannelActorState{})
|
||||
cbor.RegisterCborType(PCAConstructorParams{})
|
||||
cbor.RegisterCborType(SignedVoucher{})
|
||||
cbor.RegisterCborType(Merge{})
|
||||
cbor.RegisterCborType(LaneState{})
|
||||
cbor.RegisterCborType(UpdateChannelState{})
|
||||
}
|
||||
|
||||
type PaymentChannelActor struct{}
|
||||
|
||||
type LaneState struct {
|
||||
Closed bool
|
||||
Redeemed types.BigInt
|
||||
Nonce uint64
|
||||
}
|
||||
|
||||
type PaymentChannelActorState struct {
|
||||
From address.Address
|
||||
To address.Address
|
||||
|
||||
ChannelTotal types.BigInt
|
||||
ToSend types.BigInt
|
||||
|
||||
ClosingAt uint64
|
||||
MinCloseHeight uint64
|
||||
|
||||
LaneStates map[uint64]*LaneState
|
||||
|
||||
VerifActor address.Address
|
||||
VerifMethod uint64
|
||||
}
|
||||
|
||||
func (pca PaymentChannelActor) Exports() []interface{} {
|
||||
return []interface{}{
|
||||
0: pca.Constructor,
|
||||
1: pca.UpdateChannelState,
|
||||
2: pca.Close,
|
||||
3: pca.Collect,
|
||||
}
|
||||
}
|
||||
|
||||
type PCAConstructorParams struct {
|
||||
To address.Address
|
||||
VerifActor address.Address
|
||||
VerifMethod uint64
|
||||
}
|
||||
|
||||
func (pca PaymentChannelActor) Constructor(act *types.Actor, vmctx types.VMContext, params *PCAConstructorParams) ([]byte, ActorError) {
|
||||
var self PaymentChannelActorState
|
||||
self.From = vmctx.Origin()
|
||||
self.To = params.To
|
||||
self.VerifActor = params.VerifActor
|
||||
self.VerifMethod = params.VerifMethod
|
||||
|
||||
storage := vmctx.Storage()
|
||||
c, err := storage.Put(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := storage.Commit(EmptyCBOR, c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type SignedVoucher struct {
|
||||
TimeLock uint64
|
||||
SecretPreimage []byte
|
||||
Extra []byte
|
||||
Lane uint64
|
||||
Nonce uint64
|
||||
Amount types.BigInt
|
||||
MinCloseHeight uint64
|
||||
|
||||
Merges []Merge
|
||||
|
||||
Signature types.Signature
|
||||
}
|
||||
|
||||
type Merge struct {
|
||||
Lane uint64
|
||||
Nonce uint64
|
||||
}
|
||||
|
||||
type UpdateChannelState struct {
|
||||
Sv SignedVoucher
|
||||
Secret []byte
|
||||
Proof []byte
|
||||
}
|
||||
|
||||
func hash(b []byte) []byte {
|
||||
panic("blake 2b hash pls")
|
||||
}
|
||||
|
||||
func (pca PaymentChannelActor) UpdateChannelState(act *types.Actor, vmctx types.VMContext, params *UpdateChannelState) ([]byte, ActorError) {
|
||||
var self PaymentChannelActorState
|
||||
oldstate := vmctx.Storage().GetHead()
|
||||
storage := vmctx.Storage()
|
||||
if err := storage.Get(oldstate, &self); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sv := params.Sv
|
||||
|
||||
if err := vmctx.VerifySignature(sv.Signature, self.From); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if vmctx.BlockHeight() < sv.TimeLock {
|
||||
return nil, aerrors.New(2, "cannot use this voucher yet!")
|
||||
}
|
||||
|
||||
if sv.SecretPreimage != nil {
|
||||
if !bytes.Equal(hash(params.Secret), sv.SecretPreimage) {
|
||||
return nil, aerrors.New(3, "Incorrect secret!")
|
||||
}
|
||||
}
|
||||
|
||||
if sv.Extra != nil {
|
||||
if self.VerifActor == address.Undef {
|
||||
return nil, aerrors.New(4, "no verifActor for extra data")
|
||||
}
|
||||
|
||||
encoded, err := SerializeParams([]interface{}{sv.Extra, params.Proof})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = vmctx.Send(self.VerifActor, self.VerifMethod, types.NewInt(0), encoded)
|
||||
if err != nil {
|
||||
return nil, aerrors.New(5, "spend voucher verification failed")
|
||||
}
|
||||
}
|
||||
|
||||
ls := self.LaneStates[sv.Lane]
|
||||
if ls.Closed {
|
||||
return nil, aerrors.New(6, "cannot redeem a voucher on a closed lane")
|
||||
}
|
||||
|
||||
if ls.Nonce > sv.Nonce {
|
||||
return nil, aerrors.New(7, "voucher has an outdated nonce, cannot redeem")
|
||||
}
|
||||
|
||||
mergeValue := types.NewInt(0)
|
||||
for _, merge := range sv.Merges {
|
||||
if merge.Lane == sv.Lane {
|
||||
return nil, aerrors.New(8, "voucher cannot merge its own lane")
|
||||
}
|
||||
|
||||
ols := self.LaneStates[merge.Lane]
|
||||
|
||||
if ols.Nonce >= merge.Nonce {
|
||||
return nil, aerrors.New(9, "merge in voucher has outdated nonce, cannot redeem")
|
||||
}
|
||||
|
||||
mergeValue = types.BigAdd(mergeValue, ols.Redeemed)
|
||||
ols.Nonce = merge.Nonce
|
||||
}
|
||||
|
||||
ls.Nonce = sv.Nonce
|
||||
balanceDelta := types.BigSub(sv.Amount, types.BigAdd(mergeValue, ls.Redeemed))
|
||||
ls.Redeemed = sv.Amount
|
||||
|
||||
newSendBalance := types.BigAdd(self.ToSend, balanceDelta)
|
||||
if types.BigCmp(newSendBalance, types.NewInt(0)) < 0 {
|
||||
// TODO: is this impossible?
|
||||
return nil, aerrors.New(10, "voucher would leave channel balance negative")
|
||||
}
|
||||
|
||||
if types.BigCmp(newSendBalance, self.ChannelTotal) > 0 {
|
||||
return nil, aerrors.New(11, "not enough funds in channel to cover voucher")
|
||||
}
|
||||
|
||||
self.ToSend = newSendBalance
|
||||
|
||||
if sv.MinCloseHeight != 0 {
|
||||
if self.ClosingAt != 0 && self.ClosingAt < sv.MinCloseHeight {
|
||||
self.ClosingAt = sv.MinCloseHeight
|
||||
}
|
||||
if self.MinCloseHeight < sv.MinCloseHeight {
|
||||
self.MinCloseHeight = sv.MinCloseHeight
|
||||
}
|
||||
}
|
||||
|
||||
ncid, err := storage.Put(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := storage.Commit(oldstate, ncid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (pca PaymentChannelActor) Close(act *types.Actor, vmctx types.VMContext, params struct{}) ([]byte, aerrors.ActorError) {
|
||||
var self PaymentChannelActorState
|
||||
storage := vmctx.Storage()
|
||||
oldstate := storage.GetHead()
|
||||
if err := storage.Get(oldstate, &self); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if vmctx.Message().From != self.From && vmctx.Message().From != self.To {
|
||||
return nil, aerrors.New(1, "not authorized to close channel")
|
||||
}
|
||||
|
||||
if self.ClosingAt != 0 {
|
||||
return nil, aerrors.New(2, "channel already closing")
|
||||
}
|
||||
|
||||
self.ClosingAt = vmctx.BlockHeight() + ChannelClosingDelay
|
||||
if self.ClosingAt < self.MinCloseHeight {
|
||||
self.ClosingAt = self.MinCloseHeight
|
||||
}
|
||||
|
||||
ncid, err := storage.Put(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := storage.Commit(oldstate, ncid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (pca PaymentChannelActor) Collect(act *types.Actor, vmctx types.VMContext, params struct{}) ([]byte, aerrors.ActorError) {
|
||||
var self PaymentChannelActorState
|
||||
storage := vmctx.Storage()
|
||||
oldstate := storage.GetHead()
|
||||
if err := storage.Get(oldstate, &self); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if self.ClosingAt == 0 {
|
||||
return nil, aerrors.New(1, "payment channel not closing or closed")
|
||||
}
|
||||
|
||||
if vmctx.BlockHeight() < self.ClosingAt {
|
||||
return nil, aerrors.New(2, "payment channel not closed yet")
|
||||
}
|
||||
_, err := vmctx.Send(self.From, 0, types.BigSub(self.ChannelTotal, self.ToSend), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = vmctx.Send(self.To, 0, self.ToSend, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
self.ChannelTotal = types.NewInt(0)
|
||||
self.ToSend = types.NewInt(0)
|
||||
|
||||
ncid, err := storage.Put(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := storage.Commit(oldstate, ncid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
@ -161,7 +161,7 @@ func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
func MakeGenesisBlock(bs bstore.Blockstore, w *Wallet) (*GenesisBootstrap, error) {
|
||||
fmt.Println("at end of make Genesis block")
|
||||
|
||||
minerAddr, err := w.GenerateKey(KTSecp256k1)
|
||||
minerAddr, err := w.GenerateKey(types.KTSecp256k1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, ti
|
||||
|
||||
fmt.Printf("adding %d messages to block...", len(msgs))
|
||||
var msgCids []cid.Cid
|
||||
var blsSigs []Signature
|
||||
var blsSigs []types.Signature
|
||||
var receipts []interface{}
|
||||
for _, msg := range msgs {
|
||||
if msg.Signature.TypeCode() == 2 {
|
||||
@ -108,7 +108,7 @@ func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, ti
|
||||
return fullBlock, nil
|
||||
}
|
||||
|
||||
func aggregateSignatures(sigs []Signature) (Signature, error) {
|
||||
func aggregateSignatures(sigs []types.Signature) (types.Signature, error) {
|
||||
var blsSigs []bls.Signature
|
||||
for _, s := range sigs {
|
||||
var bsig bls.Signature
|
||||
@ -117,8 +117,8 @@ func aggregateSignatures(sigs []Signature) (Signature, error) {
|
||||
}
|
||||
|
||||
aggSig := bls.Aggregate(blsSigs)
|
||||
return Signature{
|
||||
Type: KTBLS,
|
||||
return types.Signature{
|
||||
Type: types.KTBLS,
|
||||
Data: aggSig[:],
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
@ -38,7 +37,7 @@ func init() {
|
||||
return SignedMessage{}, fmt.Errorf("signature in signed message was not bytes")
|
||||
}
|
||||
|
||||
sig, err := SignatureFromBytes(sigb)
|
||||
sig, err := types.SignatureFromBytes(sigb)
|
||||
if err != nil {
|
||||
return SignedMessage{}, err
|
||||
}
|
||||
@ -49,18 +48,6 @@ func init() {
|
||||
}, nil
|
||||
})).
|
||||
Complete())
|
||||
cbor.RegisterCborType(atlas.BuildEntry(Signature{}).Transform().
|
||||
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
||||
func(s Signature) ([]byte, error) {
|
||||
buf := make([]byte, 4)
|
||||
n := binary.PutUvarint(buf, uint64(s.TypeCode()))
|
||||
return append(buf[:n], s.Data...), nil
|
||||
})).
|
||||
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
|
||||
func(x []byte) (Signature, error) {
|
||||
return SignatureFromBytes(x)
|
||||
})).
|
||||
Complete())
|
||||
cbor.RegisterCborType(atlas.BuildEntry(BlockHeader{}).UseTag(43).Transform().
|
||||
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
||||
func(blk BlockHeader) ([]interface{}, error) {
|
||||
@ -140,7 +127,7 @@ type BlockHeader struct {
|
||||
|
||||
Messages cid.Cid
|
||||
|
||||
BLSAggregate Signature
|
||||
BLSAggregate types.Signature
|
||||
|
||||
MessageReceipts cid.Cid
|
||||
}
|
||||
@ -208,7 +195,7 @@ func (m *SignedMessage) Cid() cid.Cid {
|
||||
|
||||
type SignedMessage struct {
|
||||
Message types.Message
|
||||
Signature Signature
|
||||
Signature types.Signature
|
||||
}
|
||||
|
||||
func DecodeSignedMessage(data []byte) (*SignedMessage, error) {
|
||||
|
92
chain/types/signature.go
Normal file
92
chain/types/signature.go
Normal file
@ -0,0 +1,92 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/lib/crypto"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/minio/blake2b-simd"
|
||||
"github.com/polydawn/refmt/obj/atlas"
|
||||
)
|
||||
|
||||
const (
|
||||
KTSecp256k1 = "secp256k1"
|
||||
KTBLS = "bls"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cbor.RegisterCborType(atlas.BuildEntry(Signature{}).Transform().
|
||||
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
||||
func(s Signature) ([]byte, error) {
|
||||
buf := make([]byte, 4)
|
||||
n := binary.PutUvarint(buf, uint64(s.TypeCode()))
|
||||
return append(buf[:n], s.Data...), nil
|
||||
})).
|
||||
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
|
||||
func(x []byte) (Signature, error) {
|
||||
return SignatureFromBytes(x)
|
||||
})).
|
||||
Complete())
|
||||
}
|
||||
|
||||
type Signature struct {
|
||||
Type string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func SignatureFromBytes(x []byte) (Signature, error) {
|
||||
val, nr := binary.Uvarint(x)
|
||||
if nr != 1 {
|
||||
return Signature{}, fmt.Errorf("signatures with type field longer than one byte are invalid")
|
||||
}
|
||||
var ts string
|
||||
switch val {
|
||||
case 1:
|
||||
ts = KTSecp256k1
|
||||
default:
|
||||
return Signature{}, fmt.Errorf("unsupported signature type: %d", val)
|
||||
}
|
||||
|
||||
return Signature{
|
||||
Type: ts,
|
||||
Data: x[1:],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Signature) Verify(addr address.Address, msg []byte) error {
|
||||
b2sum := blake2b.Sum256(msg)
|
||||
|
||||
switch s.Type {
|
||||
case KTSecp256k1:
|
||||
pubk, err := crypto.EcRecover(b2sum[:], s.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
maybeaddr, err := address.NewSecp256k1Address(pubk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if addr != maybeaddr {
|
||||
return fmt.Errorf("signature did not match")
|
||||
}
|
||||
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot verify signature of unsupported type: %s", s.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Signature) TypeCode() int {
|
||||
switch s.Type {
|
||||
case KTSecp256k1:
|
||||
return 1
|
||||
case KTBLS:
|
||||
return 2
|
||||
default:
|
||||
panic("unsupported signature type")
|
||||
}
|
||||
}
|
@ -32,4 +32,5 @@ type VMContext interface {
|
||||
GasUsed() BigInt
|
||||
Storage() Storage
|
||||
StateTree() (StateTree, aerrors.ActorError)
|
||||
VerifySignature(sig Signature, from address.Address) aerrors.ActorError
|
||||
}
|
||||
|
@ -129,6 +129,10 @@ func (vmc *VMContext) StateTree() (types.StateTree, aerrors.ActorError) {
|
||||
return vmc.state, nil
|
||||
}
|
||||
|
||||
func (vmctx *VMContext) VerifySignature(sig types.Signature, act address.Address) aerrors.ActorError {
|
||||
panic("NYI")
|
||||
}
|
||||
|
||||
func (vm *VM) makeVMContext(sroot cid.Cid, origin address.Address, msg *types.Message) *VMContext {
|
||||
cst := hamt.CSTFromBstore(vm.cs.bs)
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -17,9 +15,6 @@ import (
|
||||
|
||||
const (
|
||||
KNamePrefix = "wallet-"
|
||||
|
||||
KTSecp256k1 = "secp256k1"
|
||||
KTBLS = "bls"
|
||||
)
|
||||
|
||||
type Wallet struct {
|
||||
@ -36,91 +31,31 @@ func NewWallet(keystore types.KeyStore) (*Wallet, error) {
|
||||
return w, nil
|
||||
}
|
||||
|
||||
type Signature struct {
|
||||
Type string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func SignatureFromBytes(x []byte) (Signature, error) {
|
||||
val, nr := binary.Uvarint(x)
|
||||
if nr != 1 {
|
||||
return Signature{}, fmt.Errorf("signatures with type field longer than one byte are invalid")
|
||||
}
|
||||
var ts string
|
||||
switch val {
|
||||
case 1:
|
||||
ts = KTSecp256k1
|
||||
default:
|
||||
return Signature{}, fmt.Errorf("unsupported signature type: %d", val)
|
||||
}
|
||||
|
||||
return Signature{
|
||||
Type: ts,
|
||||
Data: x[1:],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Signature) Verify(addr address.Address, msg []byte) error {
|
||||
b2sum := blake2b.Sum256(msg)
|
||||
|
||||
switch s.Type {
|
||||
case KTSecp256k1:
|
||||
pubk, err := crypto.EcRecover(b2sum[:], s.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
maybeaddr, err := address.NewSecp256k1Address(pubk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if addr != maybeaddr {
|
||||
return fmt.Errorf("signature did not match")
|
||||
}
|
||||
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot verify signature of unsupported type: %s", s.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Signature) TypeCode() int {
|
||||
switch s.Type {
|
||||
case KTSecp256k1:
|
||||
return 1
|
||||
case KTBLS:
|
||||
return 2
|
||||
default:
|
||||
panic("unsupported signature type")
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Wallet) Sign(addr address.Address, msg []byte) (*Signature, error) {
|
||||
func (w *Wallet) Sign(addr address.Address, msg []byte) (*types.Signature, error) {
|
||||
ki, err := w.findKey(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch ki.Type {
|
||||
case KTSecp256k1:
|
||||
case types.KTSecp256k1:
|
||||
b2sum := blake2b.Sum256(msg)
|
||||
sig, err := crypto.Sign(ki.PrivateKey, b2sum[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Signature{
|
||||
Type: KTSecp256k1,
|
||||
return &types.Signature{
|
||||
Type: types.KTSecp256k1,
|
||||
Data: sig,
|
||||
}, nil
|
||||
case KTBLS:
|
||||
case types.KTBLS:
|
||||
var pk bls.PrivateKey
|
||||
copy(pk[:], ki.PrivateKey)
|
||||
sig := bls.PrivateKeySign(pk, msg)
|
||||
|
||||
return &Signature{
|
||||
Type: KTBLS,
|
||||
return &types.Signature{
|
||||
Type: types.KTBLS,
|
||||
Data: sig[:],
|
||||
}, nil
|
||||
|
||||
@ -180,7 +115,7 @@ func (w *Wallet) ListAddrs() ([]address.Address, error) {
|
||||
func (w *Wallet) GenerateKey(typ string) (address.Address, error) {
|
||||
var k *Key
|
||||
switch typ {
|
||||
case KTSecp256k1:
|
||||
case types.KTSecp256k1:
|
||||
priv, err := crypto.GenerateKey()
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
@ -194,7 +129,7 @@ func (w *Wallet) GenerateKey(typ string) (address.Address, error) {
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
case KTBLS:
|
||||
case types.KTBLS:
|
||||
priv := bls.PrivateKeyGenerate()
|
||||
ki := types.KeyInfo{
|
||||
Type: typ,
|
||||
@ -231,7 +166,7 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
|
||||
}
|
||||
|
||||
switch k.Type {
|
||||
case KTSecp256k1:
|
||||
case types.KTSecp256k1:
|
||||
k.PublicKey = crypto.PublicKey(k.PrivateKey)
|
||||
|
||||
var err error
|
||||
@ -240,7 +175,7 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
|
||||
return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err)
|
||||
}
|
||||
|
||||
case KTBLS:
|
||||
case types.KTBLS:
|
||||
var pk bls.PrivateKey
|
||||
copy(pk[:], k.PrivateKey)
|
||||
pub := bls.PrivateKeyPublicKey(pk)
|
||||
|
1
go.mod
1
go.mod
@ -69,6 +69,7 @@ require (
|
||||
go4.org v0.0.0-20190313082347-94abd6928b1d // indirect
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||
google.golang.org/appengine v1.4.0 // indirect
|
||||
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8
|
||||
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
|
||||
)
|
||||
|
@ -123,7 +123,7 @@ func (a *FullNodeAPI) WalletBalance(ctx context.Context, addr address.Address) (
|
||||
return a.Chain.GetBalance(addr)
|
||||
}
|
||||
|
||||
func (a *FullNodeAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*chain.Signature, error) {
|
||||
func (a *FullNodeAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*types.Signature, error) {
|
||||
return a.Wallet.Sign(k, msg)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user