-
Notifications
You must be signed in to change notification settings - Fork 16
/
signedTransaction.go
83 lines (68 loc) · 2.75 KB
/
signedTransaction.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package aptos
import (
"errors"
"github.com/aptos-labs/aptos-go-sdk/bcs"
"github.com/aptos-labs/aptos-go-sdk/crypto"
)
// SignedTransactionVariant is the variant for a signed transaction
type SignedTransactionVariant uint8
// TransactionSigner is a generic interface for a way to sign transactions. The default implementation is Account
//
// Note that AccountAddress is needed to be the correct on-chain value for proper signing. This may differ from the
// AuthKey provided by the crypto.Signer
type TransactionSigner interface {
crypto.Signer
// AccountAddress returns the address of the signer, this may differ from the AuthKey derived from the inner signer
AccountAddress() AccountAddress
}
//region SignedTransaction
// UserTransactionVariant is the variant for a transaction submitted by a user. For now, we don't support any others,
// because they can't be submitted.
const UserTransactionVariant SignedTransactionVariant = 0
// SignedTransaction a raw transaction plus its authenticator for a fully verifiable message
type SignedTransaction struct {
Transaction RawTransactionImpl // The transaction either [RawTransaction] or [RawTransactionWithData]
Authenticator *TransactionAuthenticator // The authenticator for a transaction (can't be be a standalone [crypto.AccountAuthenticator])
}
// Verify checks a signed transaction's signature
func (txn *SignedTransaction) Verify() error {
bytes, err := txn.Transaction.SigningMessage()
if err != nil {
return err
}
if txn.Authenticator.Verify(bytes) {
return nil
}
return errors.New("signature is invalid")
}
// TransactionPrefix is a cached hash prefix for taking transaction hashes
var TransactionPrefix *[]byte
// Hash takes the hash of the SignedTransaction
//
// Note: At the moment, this assumes that the transaction is a UserTransaction
func (txn *SignedTransaction) Hash() (string, error) {
if TransactionPrefix == nil {
hash := Sha3256Hash([][]byte{[]byte("APTOS::Transaction")})
TransactionPrefix = &hash
}
txnBytes, err := bcs.Serialize(txn)
if err != nil {
return "", err
}
// Transaction signature is defined as, the domain separated prefix based on struct (Transaction)
// Then followed by the type of the transaction for the enum, UserTransaction is 0
// Then followed by BCS encoded bytes of the signed transaction
hashBytes := Sha3256Hash([][]byte{*TransactionPrefix, {byte(UserTransactionVariant)}, txnBytes})
return BytesToHex(hashBytes), nil
}
//region SignedTransaction bcs.Struct
func (txn *SignedTransaction) MarshalBCS(ser *bcs.Serializer) {
txn.Transaction.MarshalBCS(ser)
txn.Authenticator.MarshalBCS(ser)
}
func (txn *SignedTransaction) UnmarshalBCS(des *bcs.Deserializer) {
txn.Transaction.UnmarshalBCS(des)
txn.Authenticator.UnmarshalBCS(des)
}
//endregion
//endregion