-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
118 changed files
with
13,473 additions
and
4,006 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// Methods and types to interact with the authorizer nodes. | ||
// Authorizer nodes are the nodes that authorize the burn operations, whether on to be able to perform corresponding mint operations. | ||
package authorizer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package authorizer | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/0chain/gosdk_common/core/client" | ||
"github.com/0chain/gosdk_common/core/conf" | ||
"github.com/0chain/gosdk_common/core/zcncrypto" | ||
|
||
"github.com/0chain/gosdk_common/zcnbridge" | ||
|
||
"github.com/0chain/gosdk_common/core/encryption" | ||
"github.com/0chain/gosdk_common/zcnbridge/errors" | ||
) | ||
|
||
type ProofOfBurn struct { | ||
TxnID string `json:"0chain_txn_id"` | ||
Nonce int64 `json:"nonce"` | ||
Amount int64 `json:"amount"` | ||
EthereumAddress string `json:"ethereum_address"` | ||
Signature []byte `json:"signature,omitempty"` | ||
} | ||
|
||
func (pb *ProofOfBurn) Encode() []byte { | ||
return encryption.RawHash(pb) | ||
} | ||
|
||
func (pb *ProofOfBurn) Decode(input []byte) error { | ||
return json.Unmarshal(input, pb) | ||
} | ||
|
||
func (pb *ProofOfBurn) Verify() (err error) { | ||
switch { | ||
case pb.TxnID == "": | ||
err = errors.NewError("failed to verify proof of burn ticket", "0chain txn id is required") | ||
case pb.Nonce == 0: | ||
err = errors.NewError("failed to verify proof of burn ticket", "Nonce is required") | ||
case pb.Amount == 0: | ||
err = errors.NewError("failed to verify proof of burn ticket", "Amount is required") | ||
case pb.EthereumAddress == "": | ||
err = errors.NewError("failed to verify proof of burn ticket", "Receiving client id is required") | ||
} | ||
return | ||
} | ||
|
||
func (pb *ProofOfBurn) UnsignedMessage() string { | ||
return fmt.Sprintf("%v:%v:%v:%v", pb.TxnID, pb.Amount, pb.Nonce, pb.EthereumAddress) | ||
} | ||
|
||
func (pb *ProofOfBurn) SignWithEthereum(b *zcnbridge.BridgeClient) (err error) { | ||
sig, err := b.SignWithEthereumChain(pb.UnsignedMessage()) | ||
if err != nil { | ||
return errors.Wrap("signature_ethereum", "failed to sign proof-of-burn ticket", err) | ||
} | ||
pb.Signature = sig | ||
|
||
return | ||
} | ||
|
||
// Sign can sign if chain config is initialized | ||
func (pb *ProofOfBurn) Sign() (err error) { | ||
hash := zcncrypto.Sha3Sum256(pb.UnsignedMessage()) | ||
sig, err := client.Sign(hash) | ||
if err != nil { | ||
return errors.Wrap("signature_0chain", "failed to sign proof-of-burn ticket using walletString ID ", err) | ||
} | ||
pb.Signature = []byte(sig) | ||
|
||
return | ||
} | ||
|
||
// SignWith0Chain can sign with the provided walletString | ||
func (pb *ProofOfBurn) SignWith0Chain(w *zcncrypto.Wallet) (err error) { | ||
hash := zcncrypto.Sha3Sum256(pb.UnsignedMessage()) | ||
config, err := conf.GetClientConfig() | ||
|
||
if err != nil { | ||
return errors.Wrap("signature_0chain", "failed to get client config", err) | ||
} | ||
|
||
sig, err := w.Sign(hash, config.SignatureScheme) | ||
if err != nil { | ||
return errors.Wrap("signature_0chain", "failed to sign proof-of-burn ticket using walletString ID "+w.ClientID, err) | ||
} | ||
pb.Signature = []byte(sig) | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package authorizer_test | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/0chain/gosdk_common/constants" | ||
"github.com/0chain/gosdk_common/core/conf" | ||
"github.com/0chain/gosdk_common/core/zcncrypto" | ||
"github.com/0chain/gosdk_common/zcnbridge/authorizer" | ||
"github.com/stretchr/testify/require" | ||
"github.com/stretchr/testify/suite" | ||
) | ||
|
||
const walletString = `{ | ||
"client_id": "39ac4c04401762778de45d00c51934b2ff15d8168722585daa422195a1ebc5d5", | ||
"client_key": "9cf22d230343a68a149a2ccea1137846dd6d0fe653985eb8bebfbe2583ab0e1e2281b78218f480a50cac78cd0c716c3aafa8d741af813a94ca0a5b4e0b8e7a22", | ||
"keys": [ | ||
{ | ||
"public_key": "9cf22d230343a68a149a2ccea1137846dd6d0fe653985eb8bebfbe2583ab0e1e2281b78218f480a50cac78cd0c716c3aafa8d741af813a94ca0a5b4e0b8e7a22", | ||
"private_key": "9c6c9022bdbd05670c07eae339dbb5491b1c035c2287a83c56581c505b824623" | ||
} | ||
], | ||
"mnemonics": "fortune guitar marine bachelor ocean raven hunt silver pass hurt industry forget cradle shuffle render used used order chat shallow aerobic cry exercise junior", | ||
"version": "1.0", | ||
"date_created": "2022-07-17T16:12:25+05:00", | ||
"nonce": 0 | ||
} | ||
` | ||
|
||
type TicketTestSuite struct { | ||
suite.Suite | ||
w *zcncrypto.Wallet | ||
} | ||
|
||
func TestTicketTestSuite(t *testing.T) { | ||
suite.Run(t, new(TicketTestSuite)) | ||
} | ||
|
||
func (suite *TicketTestSuite) SetupTest() { | ||
w := &zcncrypto.Wallet{} | ||
err := json.Unmarshal([]byte(walletString), w) | ||
require.NoError(suite.T(), err) | ||
suite.w = w | ||
} | ||
|
||
func (suite *TicketTestSuite) TestBasicSignature() { | ||
hash := zcncrypto.Sha3Sum256("test") | ||
signScheme := zcncrypto.NewSignatureScheme("bls0chain") | ||
err := signScheme.SetPrivateKey(suite.w.Keys[0].PrivateKey) | ||
require.NoError(suite.T(), err) | ||
sign, err := signScheme.Sign(hash) | ||
require.NoError(suite.T(), err) | ||
require.NotEmpty(suite.T(), sign) | ||
} | ||
|
||
func (suite *TicketTestSuite) TestTicketSignature() { | ||
pb := &authorizer.ProofOfBurn{ | ||
TxnID: "TxnID", | ||
Nonce: 100, | ||
Amount: 10, | ||
EthereumAddress: "0xBEEF", | ||
Signature: nil, | ||
} | ||
|
||
conf.InitClientConfig(&conf.Config{ | ||
SignatureScheme: constants.BLS0CHAIN.String(), | ||
}) | ||
err := pb.SignWith0Chain(suite.w) | ||
require.NoError(suite.T(), err) | ||
require.NotEmpty(suite.T(), pb.Signature) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package zcnbridge | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
) | ||
|
||
type ( | ||
// JobStatus = Ethereum transaction status | ||
JobStatus uint | ||
// JobResult = Authorizer task result, it wraps actual result of the query inside authorizer | ||
JobResult interface { | ||
// Error = Status of Authorizer job on authorizer server | ||
Error() error | ||
// Data returns the actual result | ||
Data() interface{} | ||
// SetAuthorizerID Assigns authorizer ID to the Job | ||
SetAuthorizerID(ID string) | ||
// GetAuthorizerID returns authorizer ID | ||
GetAuthorizerID() string | ||
} | ||
// JobError result of internal request wrapped in authorizer job | ||
JobError struct { | ||
error | ||
} | ||
|
||
// EthereumBurnEvents represents burn events returned by authorizers | ||
EthereumBurnEvents struct { | ||
AuthorizerID string `json:"authorizer_id,omitempty"` | ||
BurnEvents []struct { | ||
Nonce int64 `json:"nonce"` | ||
Amount int64 `json:"amount"` | ||
TransactionHash string `json:"transaction_hash"` | ||
} `json:"burn_events"` | ||
} | ||
|
||
// ProofEthereumBurn Authorizer returns this type for Ethereum transaction | ||
ProofEthereumBurn struct { | ||
TxnID string `json:"ethereum_txn_id"` | ||
Nonce int64 `json:"nonce"` | ||
Amount int64 `json:"amount"` | ||
ReceivingClientID string `json:"receiving_client_id"` // 0ZCN address | ||
Signature string `json:"signature"` | ||
} | ||
|
||
// ProofZCNBurn Authorizer returns this type for ZCN transaction | ||
ProofZCNBurn struct { | ||
AuthorizerID string `json:"authorizer_id,omitempty"` | ||
TxnID string `json:"0chain_txn_id"` | ||
To string `json:"to"` | ||
Nonce int64 `json:"nonce"` | ||
Amount int64 `json:"amount"` | ||
Signature []byte `json:"signature"` | ||
} | ||
) | ||
|
||
func (e *JobError) UnmarshalJSON(buf []byte) error { | ||
e.error = errors.New(string(buf)) | ||
return nil | ||
} | ||
|
||
func (e *JobError) MarshalJSON() ([]byte, error) { | ||
return json.Marshal(e.Error()) | ||
} | ||
|
||
// WZCNBurnEvent returned from burn ticket handler of: /v1/ether/burnticket/get | ||
type WZCNBurnEvent struct { | ||
// AuthorizerID Authorizer ID | ||
AuthorizerID string `json:"authorizer_id,omitempty"` | ||
// BurnTicket Returns burn ticket | ||
BurnTicket *ProofEthereumBurn `json:"ticket,omitempty"` | ||
// Err gives error of job on server side | ||
Err *JobError `json:"err,omitempty"` | ||
// Status gives job status on server side (authoriser) | ||
Status JobStatus `json:"status,omitempty"` | ||
} | ||
|
||
func (r *WZCNBurnEvent) GetAuthorizerID() string { | ||
return r.AuthorizerID | ||
} | ||
|
||
func (r *WZCNBurnEvent) SetAuthorizerID(id string) { | ||
r.AuthorizerID = id | ||
} | ||
|
||
func (r *WZCNBurnEvent) Error() error { | ||
return r.Err | ||
} | ||
|
||
func (r *WZCNBurnEvent) Data() interface{} { | ||
return r.BurnTicket | ||
} | ||
|
||
func (r *EthereumBurnEvents) GetAuthorizerID() string { | ||
return r.AuthorizerID | ||
} | ||
|
||
func (r *EthereumBurnEvents) SetAuthorizerID(id string) { | ||
r.AuthorizerID = id | ||
} | ||
|
||
func (r *EthereumBurnEvents) Error() error { | ||
return nil | ||
} | ||
|
||
func (r *EthereumBurnEvents) Data() interface{} { | ||
return r | ||
} | ||
|
||
func (r *ProofZCNBurn) GetAuthorizerID() string { | ||
return r.AuthorizerID | ||
} | ||
|
||
func (r *ProofZCNBurn) SetAuthorizerID(id string) { | ||
r.AuthorizerID = id | ||
} | ||
|
||
func (r *ProofZCNBurn) Error() error { | ||
return nil | ||
} | ||
|
||
func (r *ProofZCNBurn) Data() interface{} { | ||
return r | ||
} |
Oops, something went wrong.