Sign invokes a callback function to add signatures to Inputs and Issuances in the template. The callback adds as many as it can, up to the number needed for each Input or Issuance. Multiple calls to Sign might be necessary to marshal enough signatures to authorize a transaction, each with a callback
(ctx context.Context, signFn SignFunc)
| 304 | // transaction, each with a callback invoking a different signing HSM |
| 305 | // responsible for a different subset of keys. |
| 306 | func (tpl *Template) Sign(ctx context.Context, signFn SignFunc) error { |
| 307 | txID, _, err := tpl.Materialize() |
| 308 | if err != nil { |
| 309 | return errors.Wrap(err, "cannot get txid for computing signature message") |
| 310 | } |
| 311 | |
| 312 | txidProg := standard.VerifyTxID(txID.Byte32()) |
| 313 | callSign := func(quorum int, keyIDs [][]byte, inPath []i10rjson.HexBytes, anchor []byte, sigs *[]i10rjson.HexBytes) error { |
| 314 | if *sigs == nil { |
| 315 | *sigs = make([]i10rjson.HexBytes, len(keyIDs)) |
| 316 | } |
| 317 | |
| 318 | // Have we already reached a quorum? |
| 319 | for _, s := range *sigs { |
| 320 | if len(s) > 0 { |
| 321 | quorum-- |
| 322 | if quorum <= 0 { |
| 323 | return nil |
| 324 | } |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | path := asBytes(inPath) |
| 329 | msg := append(txidProg, anchor...) |
| 330 | |
| 331 | for i, keyID := range keyIDs { |
| 332 | if len((*sigs)[i]) > 0 { |
| 333 | // We already have a signature for this key, skip it |
| 334 | continue |
| 335 | } |
| 336 | sig, err := signFn(ctx, msg, keyID, path) |
| 337 | if err != nil { |
| 338 | return err |
| 339 | } |
| 340 | if len(sig) > 0 { |
| 341 | (*sigs)[i] = sig |
| 342 | quorum-- |
| 343 | if quorum <= 0 { |
| 344 | return nil |
| 345 | } |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | return nil |
| 350 | } |
| 351 | |
| 352 | for _, iss := range tpl.Issuances { |
| 353 | err := callSign(iss.Quorum, asBytes(iss.KeyHashes), iss.Path, iss.anchor, &iss.Sigs) |
| 354 | if err != nil { |
| 355 | return err |
| 356 | } |
| 357 | } |
| 358 | for _, inp := range tpl.Inputs { |
| 359 | err := callSign(inp.Quorum, asBytes(inp.KeyHashes), inp.Path, inp.Anchor, &inp.Sigs) |
| 360 | if err != nil { |
| 361 | return err |
| 362 | } |
| 363 | } |