@@ -24,12 +24,15 @@ import (
2424
2525const ProtocolV1 = 1
2626
27+ // ActionInput represents a single input to a transfer action.
28+ // It includes the token identifier, the token itself, and an optional upgrade witness.
2729type ActionInput struct {
2830 ID * token2.ID
2931 Token * token.Token
3032 UpgradeWitness * token.UpgradeWitness
3133}
3234
35+ // ToProtos converts the ActionInput to its protobuf representation.
3336func (a * ActionInput ) ToProtos () (* actions.TransferActionInput , error ) {
3437 var id * actions.TokenID
3538 if a .ID != nil {
@@ -76,6 +79,7 @@ func (a *ActionInput) ToProtos() (*actions.TransferActionInput, error) {
7679 }, nil
7780}
7881
82+ // FromProtos populates the ActionInput from its protobuf representation.
7983func (a * ActionInput ) FromProtos (input * actions.TransferActionInput ) error {
8084 if input .TokenId != nil {
8185 a .ID = & token2.ID {
@@ -117,7 +121,7 @@ func (a *ActionInput) FromProtos(input *actions.TransferActionInput) error {
117121
118122// Action specifies a transfer of one or more tokens
119123type Action struct {
120- // Inputs specify the identifiers in of the tokens to be spent
124+ // Inputs specify the tokens to be spent
121125 Inputs []* ActionInput
122126 // Outputs are the new tokens resulting from the transfer
123127 Outputs []* token.Token
@@ -129,13 +133,13 @@ type Action struct {
129133 Issuer driver.Identity
130134}
131135
132- // NewTransfer returns the Action that matches the passed arguments
133- func NewTransfer (tokenIDs []* token2.ID , inputToken []* token.Token , commitments []* math.G1 , owners [][]byte , proof []byte ) (* Action , error ) {
136+ // NewAction returns the Action that matches the passed arguments
137+ func NewAction (tokenIDs []* token2.ID , inputToken []* token.Token , commitments []* math.G1 , owners [][]byte , proof []byte ) (* Action , error ) {
134138 if len (commitments ) != len (owners ) {
135- return nil , errors .Errorf ( "number of recipients [%d] does not match number of outputs [%d]" , len (commitments ), len (owners ))
139+ return nil , errors .Wrapf ( ErrMismatchedRecipientsOutputs , "number of recipients [%d] does not match number of outputs [%d]" , len (commitments ), len (owners ))
136140 }
137141 if len (tokenIDs ) != len (inputToken ) {
138- return nil , errors .Errorf ( "number of inputs [%d] does not match number of input tokens [%d]" , len (tokenIDs ), len (inputToken ))
142+ return nil , errors .Wrapf ( ErrMismatchedInputsTokens , "number of inputs [%d] does not match number of input tokens [%d]" , len (tokenIDs ), len (inputToken ))
139143 }
140144
141145 inputs := make ([]* ActionInput , len (tokenIDs ))
@@ -160,11 +164,23 @@ func NewTransfer(tokenIDs []*token2.ID, inputToken []*token.Token, commitments [
160164 }, nil
161165}
162166
167+ // NewActionFromProtos creates a new action from protos
168+ func NewActionFromProtos (raw []byte ) (* Action , error ) {
169+ action := & Action {}
170+ err := action .Deserialize (raw )
171+ if err != nil {
172+ return nil , err
173+ }
174+
175+ return action , nil
176+ }
177+
178+ // NumInputs returns the number of inputs in the Action
163179func (t * Action ) NumInputs () int {
164180 return len (t .Inputs )
165181}
166182
167- // GetInputs returns the inputs in the Action
183+ // GetInputs returns the identifiers of the tokens spent in the Action
168184func (t * Action ) GetInputs () []* token2.ID {
169185 res := make ([]* token2.ID , len (t .Inputs ))
170186 for i , input := range t .Inputs {
@@ -174,6 +190,7 @@ func (t *Action) GetInputs() []*token2.ID {
174190 return res
175191}
176192
193+ // GetSerializedInputs returns the serialized tokens spent in the Action
177194func (t * Action ) GetSerializedInputs () ([][]byte , error ) {
178195 var res [][]byte
179196 for _ , input := range t .Inputs {
@@ -201,6 +218,7 @@ func (t *Action) GetSerializedInputs() ([][]byte, error) {
201218 return res , nil
202219}
203220
221+ // GetSerialNumbers returns nil as zkatdlog doesn't use serial numbers for graph hiding
204222func (t * Action ) GetSerialNumbers () []string {
205223 return nil
206224}
@@ -225,7 +243,7 @@ func (t *Action) IsRedeemAt(index int) bool {
225243 return t .Outputs [index ].IsRedeem ()
226244}
227245
228- // IsRedeem checks if this action is a Redeem Transfer
246+ // IsRedeem checks if this action contains any redeemed outputs
229247func (t * Action ) IsRedeem () bool {
230248 for _ , output := range t .Outputs {
231249 if output .IsRedeem () {
@@ -255,38 +273,38 @@ func (t *Action) GetSerializedOutputs() ([][]byte, error) {
255273 return res , nil
256274}
257275
258- // IsGraphHiding returns false
259- // zkatdlog is not graph hiding
276+ // IsGraphHiding returns false as zkatdlog is not graph hiding
260277func (t * Action ) IsGraphHiding () bool {
261278 return false
262279}
263280
264- // GetMetadata returns metadata of the Action
281+ // GetMetadata returns the metadata of the Action
265282func (t * Action ) GetMetadata () map [string ][]byte {
266283 return t .Metadata
267284}
268285
269- // GetIssuer returns the issuer to sign the transaction
286+ // GetIssuer returns the identity of the issuer who must sign the transaction
270287func (t * Action ) GetIssuer () driver.Identity {
271288 return t .Issuer
272289}
273290
291+ // Validate ensures the Action is well-formed
274292func (t * Action ) Validate () error {
275293 if len (t .Inputs ) == 0 {
276- return errors . Errorf ( "invalid number of token inputs, expected at least 1" )
294+ return ErrInvalidInputs
277295 }
278296 for i , in := range t .Inputs {
279297 if in == nil {
280- return errors .Errorf ( "invalid input at index [%d], empty input" , i )
298+ return errors .Wrapf ( ErrEmptyInput , "invalid input at index [%d], empty input" , i )
281299 }
282300 if in .ID == nil {
283- return errors .Errorf ( "invalid input's ID at index [%d], it is empty" , i )
301+ return errors .Wrapf ( ErrEmptyInputID , "invalid input's ID at index [%d], it is empty" , i )
284302 }
285303 if len (in .ID .TxId ) == 0 {
286- return errors .Errorf ( "invalid input's ID at index [%d], tx id is empty" , i )
304+ return errors .Wrapf ( ErrEmptyInputTxID , "invalid input's ID at index [%d], tx id is empty" , i )
287305 }
288306 if in .Token == nil {
289- return errors .Errorf ( "invalid input's token at index [%d], empty token" , i )
307+ return errors .Wrapf ( ErrEmptyInputToken , "invalid input's token at index [%d], empty token" , i )
290308 }
291309 if err := in .Token .Validate (true ); err != nil {
292310 return errors .Wrapf (err , "invalid input token at index [%d]" , i )
@@ -299,28 +317,29 @@ func (t *Action) Validate() error {
299317 }
300318 }
301319 if len (t .Outputs ) == 0 {
302- return errors . Errorf ( "invalid number of token outputs, expected at least 1" )
320+ return ErrInvalidOutputs
303321 }
304322 for i , out := range t .Outputs {
305323 if out == nil {
306- return errors .Errorf ( "invalid output token at index [%d]" , i )
324+ return errors .Wrapf ( ErrEmptyOutputToken , "invalid output token at index [%d]" , i )
307325 }
308326 if err := out .Validate (false ); err != nil {
309327 return errors .Wrapf (err , "invalid output at index [%d]" , i )
310328 }
311329 }
312330 if t .IsRedeem () && (t .Issuer == nil ) {
313- return errors . Errorf ( "Expected Issuer for a Redeem action" )
331+ return ErrMissingIssuer
314332 }
315333
316334 return nil
317335}
318336
337+ // ExtraSigners returns nil as zkatdlog doesn't require extra signers
319338func (t * Action ) ExtraSigners () []driver.Identity {
320339 return nil
321340}
322341
323- // Serialize marshal TransferAction
342+ // Serialize marshals the TransferAction to bytes
324343func (t * Action ) Serialize () ([]byte , error ) {
325344 // inputs
326345 inputs , err := protos.ToProtosSlice [actions.TransferActionInput , * ActionInput ](t .Inputs )
@@ -367,24 +386,24 @@ func (t *Action) Serialize() ([]byte, error) {
367386 return proto .Marshal (action )
368387}
369388
370- // Deserialize un-marshals TransferAction
389+ // Deserialize un-marshals a TransferAction from bytes
371390func (t * Action ) Deserialize (raw []byte ) error {
372391 action := & actions.TransferAction {}
373392 err := proto .Unmarshal (raw , action )
374393 if err != nil {
375- return errors .Wrap (err , "failed to deserialize issue action" )
394+ return errors .Wrap (err , "failed to deserialize transfer action" )
376395 }
377396
378397 // assert version
379398 if action .Version != ProtocolV1 {
380- return errors .Errorf ( "invalid issue version, expected [%d], got [%d]" , ProtocolV1 , action .Version )
399+ return errors .Wrapf ( ErrInvalidVersion , " expected [%d], got [%d]" , ProtocolV1 , action .Version )
381400 }
382401
383402 // inputs
384403 t .Inputs = make ([]* ActionInput , len (action .Inputs ))
385404 t .Inputs = slices.GenericSliceOfPointers [ActionInput ](len (action .Inputs ))
386405 if err := protos .FromProtosSlice (action .Inputs , t .Inputs ); err != nil {
387- return errors .Wrap (err , "failed unmarshalling receivers metadata " )
406+ return errors .Wrap (err , "failed unmarshalling inputs " )
388407 }
389408
390409 // outputs
@@ -417,12 +436,12 @@ func (t *Action) Deserialize(raw []byte) error {
417436 return nil
418437}
419438
420- // GetProof returns the proof in the Action
439+ // GetProof returns the zero-knowledge proof in the Action
421440func (t * Action ) GetProof () []byte {
422441 return t .Proof
423442}
424443
425- // GetOutputCommitments returns the Pedersen commitments in the Action
444+ // GetOutputCommitments returns the cryptographic commitments of the outputs
426445func (t * Action ) GetOutputCommitments () []* math.G1 {
427446 com := make ([]* math.G1 , len (t .Outputs ))
428447 for i := 0 ; i < len (com ); i ++ {
@@ -432,6 +451,7 @@ func (t *Action) GetOutputCommitments() []*math.G1 {
432451 return com
433452}
434453
454+ // InputTokens returns the tokens spent in the Action
435455func (t * Action ) InputTokens () []* token.Token {
436456 tokens := make ([]* token.Token , len (t .Inputs ))
437457 for i , in := range t .Inputs {
0 commit comments