-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathissue.go
More file actions
91 lines (76 loc) · 3.39 KB
/
Copy pathissue.go
File metadata and controls
91 lines (76 loc) · 3.39 KB
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
84
85
86
87
88
89
90
91
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package cash
import (
"encoding/json"
"github.com/LFDT-Panurus/panurus/token/services/ttx"
"github.com/LFDT-Panurus/panurus/token/token"
"github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/assert"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/id"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
)
// IssueCash contains the input information to issue a token
type IssueCash struct {
// IssuerWallet is the issuer's wallet to use
IssuerWallet string
// TokenType is the type of token to issue
TokenType token.Type
// Quantity represent the number of units of a certain token type stored in the token
Quantity uint64
// Recipient is an identifier of the recipient identity
Recipient string
}
type IssueCashView struct {
*IssueCash
}
func (p *IssueCashView) Call(context view.Context) (any, error) {
// As a first step operation, the issuer contacts the recipient's FSC node
// to ask for the identity to use to assign ownership of the freshly created token.
// Notice that, this step would not be required if the issuer knew already which
// identity the recipient wants to use.
recipient, err := ttx.RequestRecipientIdentity(context, view.Identity(p.Recipient))
assert.NoError(err, "failed getting recipient identity")
// At this point, the issuer is ready to prepare the token transaction.
// The issuer creates an anonymous transaction (this means that the result Fabric transaction will be signed using idemix),
// and specify the auditor that must be contacted to approve the operation
idProvider, err := id.GetProvider(context)
assert.NoError(err, "failed getting identity provider")
tx, err := ttx.NewAnonymousTransaction(
context,
ttx.WithAuditor(idProvider.Identity("auditor")),
)
assert.NoError(err, "failed creating issue transaction")
// The issuer adds a new issue operation to the transaction following the instruction received
wallet := ttx.GetIssuerWallet(context, p.IssuerWallet)
assert.NotNil(wallet, "issuer wallet [%s] not found", p.IssuerWallet)
err = tx.Issue(
context.Context(),
wallet,
recipient,
p.TokenType,
p.Quantity,
)
assert.NoError(err, "failed adding new issued token")
// The issuer is ready to collect all the required signatures.
// In this case, the issuer's and the auditor's signatures.
// Invoke the Token Chaincode to collect endorsements on the Token Request and prepare the relative Fabric transaction.
// This is all done in one shot running the following view.
// Before completing, all recipients receive the approved Fabric transaction.
// Depending on the token driver implementation, the recipient's signature might or might not be needed to make
// the token transaction valid.
_, err = context.RunView(ttx.NewCollectEndorsementsView(tx))
assert.NoError(err, "failed to sign issue transaction")
// Last but not least, the issuer sends the transaction for ordering and waits for transaction finality.
_, err = context.RunView(ttx.NewOrderingAndFinalityView(tx))
assert.NoError(err, "failed to commit issue transaction")
return tx.ID(), nil
}
type IssueCashViewFactory struct{}
func (p *IssueCashViewFactory) NewView(in []byte) (view.View, error) {
f := &IssueCashView{IssueCash: &IssueCash{}}
err := json.Unmarshal(in, f.IssueCash)
assert.NoError(err, "failed unmarshalling input")
return f, nil
}