github.com/koko1123/flow-go-1@v0.29.6/model/flow/account.go (about) 1 // (c) 2019 Dapper Labs - ALL RIGHTS RESERVED 2 3 package flow 4 5 import ( 6 "encoding/json" 7 "fmt" 8 9 "github.com/onflow/flow-go/crypto" 10 "github.com/onflow/flow-go/crypto/hash" 11 ) 12 13 // Account represents an account on the Flow network. 14 // 15 // An account can be an externally owned account or a contract account with code. 16 type Account struct { 17 Address Address 18 Balance uint64 19 Keys []AccountPublicKey 20 Contracts map[string][]byte 21 } 22 23 // AccountPublicKey is a public key associated with an account. 24 // 25 // An account public key contains the public key, signing and hashing algorithms, and a key weight. 26 type AccountPublicKey struct { 27 Index int 28 PublicKey crypto.PublicKey 29 SignAlgo crypto.SigningAlgorithm 30 HashAlgo hash.HashingAlgorithm 31 SeqNumber uint64 32 Weight int 33 Revoked bool 34 } 35 36 func (a AccountPublicKey) MarshalJSON() ([]byte, error) { 37 return json.Marshal(struct { 38 PublicKey []byte 39 SignAlgo crypto.SigningAlgorithm 40 HashAlgo hash.HashingAlgorithm 41 SeqNumber uint64 42 Weight int 43 }{ 44 a.PublicKey.Encode(), 45 a.SignAlgo, 46 a.HashAlgo, 47 a.SeqNumber, 48 a.Weight, 49 }) 50 } 51 52 func (a *AccountPublicKey) UnmarshalJSON(data []byte) error { 53 temp := struct { 54 PublicKey []byte 55 SignAlgo crypto.SigningAlgorithm 56 HashAlgo hash.HashingAlgorithm 57 SeqNumber uint64 58 Weight int 59 }{} 60 err := json.Unmarshal(data, &temp) 61 if err != nil { 62 return err 63 } 64 if a == nil { 65 a = new(AccountPublicKey) 66 } 67 a.PublicKey, err = crypto.DecodePublicKey(temp.SignAlgo, temp.PublicKey) 68 if err != nil { 69 return err 70 } 71 a.SignAlgo = temp.SignAlgo 72 a.HashAlgo = temp.HashAlgo 73 a.SeqNumber = temp.SeqNumber 74 a.Weight = temp.Weight 75 return nil 76 } 77 78 // Validate returns an error if this account key is invalid. 79 // 80 // An account key can be invalid for the following reasons: 81 // - It specifies an incompatible signature/hash algorithm pairing 82 // - (TODO) It specifies a negative key weight 83 func (a AccountPublicKey) Validate() error { 84 if !CompatibleAlgorithms(a.SignAlgo, a.HashAlgo) { 85 return fmt.Errorf( 86 "signing algorithm (%s) is incompatible with hashing algorithm (%s)", 87 a.SignAlgo, 88 a.HashAlgo, 89 ) 90 } 91 return nil 92 } 93 94 // AccountPrivateKey is a private key associated with an account. 95 type AccountPrivateKey struct { 96 PrivateKey crypto.PrivateKey 97 SignAlgo crypto.SigningAlgorithm 98 HashAlgo hash.HashingAlgorithm 99 } 100 101 // PublicKey returns a weighted public key. 102 func (a AccountPrivateKey) PublicKey(weight int) AccountPublicKey { 103 return AccountPublicKey{ 104 PublicKey: a.PrivateKey.PublicKey(), 105 SignAlgo: a.SignAlgo, 106 HashAlgo: a.HashAlgo, 107 Weight: weight, 108 } 109 } 110 111 func (a AccountPrivateKey) MarshalJSON() ([]byte, error) { 112 return json.Marshal(struct { 113 PrivateKey []byte 114 SignAlgo crypto.SigningAlgorithm 115 HashAlgo hash.HashingAlgorithm 116 }{ 117 a.PrivateKey.Encode(), 118 a.SignAlgo, 119 a.HashAlgo, 120 }) 121 } 122 123 // CompatibleAlgorithms returns true if the signature and hash algorithms are compatible. 124 func CompatibleAlgorithms(sigAlgo crypto.SigningAlgorithm, hashAlgo hash.HashingAlgorithm) bool { 125 switch sigAlgo { 126 case crypto.ECDSAP256, crypto.ECDSASecp256k1: 127 switch hashAlgo { 128 case hash.SHA2_256, hash.SHA3_256: 129 return true 130 } 131 } 132 return false 133 }