OSDN Git Service

chore(cli): delete getDifficultyCmd and getHashRateCmd from bytomcli (#2077)
[bytom/bytom.git] / contract / contract.go
1 package contract
2
3 import (
4         "encoding/json"
5         "sync"
6
7         dbm "github.com/bytom/bytom/database/leveldb"
8         chainjson "github.com/bytom/bytom/encoding/json"
9         "github.com/bytom/bytom/errors"
10 )
11
12 var (
13         userContractPrefix = []byte("UC:")
14 )
15
16 // pre-define errors for supporting bytom errorFormatter
17 var (
18         ErrContractDuplicated = errors.New("contract is duplicated")
19         ErrContractNotFound   = errors.New("contract not found")
20 )
21
22 // userContractKey return user contract key
23 func userContractKey(hash chainjson.HexBytes) []byte {
24         return append(userContractPrefix, hash[:]...)
25 }
26
27 // Registry tracks and stores all user contract.
28 type Registry struct {
29         db         dbm.DB
30         contractMu sync.Mutex
31 }
32
33 //NewRegistry create new registry
34 func NewRegistry(db dbm.DB) *Registry {
35         return &Registry{
36                 db: db,
37         }
38 }
39
40 //Contract describe user contract
41 type Contract struct {
42         Hash            chainjson.HexBytes `json:"id"`
43         Alias           string             `json:"alias"`
44         Contract        chainjson.HexBytes `json:"contract"`
45         CallProgram     chainjson.HexBytes `json:"call_program"`
46         RegisterProgram chainjson.HexBytes `json:"register_program"`
47 }
48
49 // SaveContract save user contract
50 func (reg *Registry) SaveContract(contract *Contract) error {
51         reg.contractMu.Lock()
52         defer reg.contractMu.Unlock()
53
54         contractKey := userContractKey(contract.Hash)
55         if existContract := reg.db.Get(contractKey); existContract != nil {
56                 return ErrContractDuplicated
57         }
58
59         rawContract, err := json.Marshal(contract)
60         if err != nil {
61                 return err
62         }
63
64         reg.db.Set(contractKey, rawContract)
65         return nil
66 }
67
68 //UpdateContract updates user contract alias
69 func (reg *Registry) UpdateContract(hash chainjson.HexBytes, alias string) error {
70         reg.contractMu.Lock()
71         defer reg.contractMu.Unlock()
72
73         contract, err := reg.GetContract(hash)
74         if err != nil {
75                 return err
76         }
77
78         contract.Alias = alias
79         rawContract, err := json.Marshal(contract)
80         if err != nil {
81                 return err
82         }
83
84         reg.db.Set(userContractKey(hash), rawContract)
85         return nil
86 }
87
88 // GetContract get user contract
89 func (reg *Registry) GetContract(hash chainjson.HexBytes) (*Contract, error) {
90         contract := &Contract{}
91         if rawContract := reg.db.Get(userContractKey(hash)); rawContract != nil {
92                 return contract, json.Unmarshal(rawContract, contract)
93         }
94         return nil, ErrContractNotFound
95 }
96
97 // ListContracts returns user contracts
98 func (reg *Registry) ListContracts() ([]*Contract, error) {
99         contracts := []*Contract{}
100         contractIter := reg.db.IteratorPrefix(userContractPrefix)
101         defer contractIter.Release()
102
103         for contractIter.Next() {
104                 contract := &Contract{}
105                 if err := json.Unmarshal(contractIter.Value(), contract); err != nil {
106                         return nil, err
107                 }
108
109                 contracts = append(contracts, contract)
110         }
111         return contracts, nil
112 }