code: func (txEnv *Envelope) Verify(getter acmstate.AccountGetter, chainID string) error {
  	err := txEnv.Validate()
  	if err != nil {
  		return err
  	}
  	errPrefix := fmt.Sprintf("could not verify transaction %X", txEnv.Tx.Hash())
  	if txEnv.Tx.ChainID != chainID {
  		return fmt.Errorf("%s: ChainID in envelope is %s but receiving chain has ID %s",
  			errPrefix, txEnv.Tx.ChainID, chainID)
  	}
  	inputs := txEnv.Tx.GetInputs()
  	if len(inputs) != len(txEnv.Signatories) {
  		return fmt.Errorf("%s: number of inputs (= %v) should equal number of signatories (= %v)",
  			errPrefix, len(inputs), len(txEnv.Signatories))
  	}
  	signBytes, err := txEnv.Tx.SignBytes()
  	if err != nil {
  		return fmt.Errorf("%s: could not generate SignBytes: %v", errPrefix, err)
  	}
  	// Expect order to match (we could build lookup but we want Verify to be quicker than Sign which does order sigs)
  	for i, s := range txEnv.Signatories {
  		if inputs[i].Address != *s.Address {
  			return fmt.Errorf("signatory %v has address %v but input %v has address %v",
  				i, *s.Address, i, inputs[i].Address)
  		}
  		err = s.PublicKey.Verify(signBytes, s.Signature)
  		if err != nil {
  			return fmt.Errorf("invalid signature in signatory %v: %v", *s.Address, err)
  		}
  	}
  	return nil
  }
docs: // Verifies the validity of the Signatories' Signatures in the Envelope. The Signatories must
  // appear in the same order as the inputs as returned by Tx.GetInputs().