// PayToSSRtx creates a new script to pay a transaction output to a // public key hash, but tags the output with OP_SSRTX. For use in constructing // valid SSRtx. func PayToSSRtx(addr dcrutil.Address) ([]byte, error) { if addr == nil { return nil, ErrUnsupportedAddress } // Only pay to pubkey hash and pay to script hash are // supported. scriptType := PubKeyHashTy switch addr := addr.(type) { case *dcrutil.AddressPubKeyHash: if addr.DSA(addr.Net()) != chainec.ECTypeSecp256k1 { return nil, ErrUnsupportedAddress } break case *dcrutil.AddressScriptHash: scriptType = ScriptHashTy break default: return nil, ErrUnsupportedAddress } hash := addr.ScriptAddress() if scriptType == PubKeyHashTy { return NewScriptBuilder().AddOp(OP_SSRTX).AddOp(OP_DUP). AddOp(OP_HASH160).AddData(hash).AddOp(OP_EQUALVERIFY). AddOp(OP_CHECKSIG).Script() } return NewScriptBuilder().AddOp(OP_SSRTX).AddOp(OP_HASH160). AddData(hash).AddOp(OP_EQUAL).Script() }
// GenerateSStxAddrPush generates an OP_RETURN push for SSGen payment addresses in // an SStx. func GenerateSStxAddrPush(addr dcrutil.Address, amount dcrutil.Amount, limits uint16) ([]byte, error) { if addr == nil { return nil, ErrUnsupportedAddress } // Only pay to pubkey hash and pay to script hash are // supported. scriptType := PubKeyHashTy switch addr := addr.(type) { case *dcrutil.AddressPubKeyHash: if addr.DSA(addr.Net()) != chainec.ECTypeSecp256k1 { return nil, ErrUnsupportedAddress } break case *dcrutil.AddressScriptHash: scriptType = ScriptHashTy break default: return nil, ErrUnsupportedAddress } // Prefix dataPushes := []byte{ 0x6a, // OP_RETURN 0x1e, // OP_DATA_30 } hash := addr.ScriptAddress() amountBuffer := make([]byte, 8) binary.LittleEndian.PutUint64(amountBuffer, uint64(amount)) // Set the bit flag indicating pay to script hash. if scriptType == ScriptHashTy { amountBuffer[7] |= 1 << 7 } limitsBuffer := make([]byte, 2) binary.LittleEndian.PutUint16(limitsBuffer, limits) // Concatenate the prefix, pubkeyhash, and amount. addrOut := append(dataPushes, hash...) addrOut = append(addrOut, amountBuffer...) addrOut = append(addrOut, limitsBuffer...) return addrOut, nil }
// PayToAddrScript creates a new script to pay a transaction output to a the // specified address. func PayToAddrScript(addr dcrutil.Address) ([]byte, error) { switch addr := addr.(type) { case *dcrutil.AddressPubKeyHash: if addr == nil { return nil, ErrUnsupportedAddress } switch addr.DSA(addr.Net()) { case chainec.ECTypeSecp256k1: return payToPubKeyHashScript(addr.ScriptAddress()) case chainec.ECTypeEdwards: return payToPubKeyHashEdwardsScript(addr.ScriptAddress()) case chainec.ECTypeSecSchnorr: return payToPubKeyHashSchnorrScript(addr.ScriptAddress()) } case *dcrutil.AddressScriptHash: if addr == nil { return nil, ErrUnsupportedAddress } return payToScriptHashScript(addr.ScriptAddress()) case *dcrutil.AddressSecpPubKey: if addr == nil { return nil, ErrUnsupportedAddress } return payToPubKeyScript(addr.ScriptAddress()) case *dcrutil.AddressEdwardsPubKey: if addr == nil { return nil, ErrUnsupportedAddress } return payToEdwardsPubKeyScript(addr.ScriptAddress()) case *dcrutil.AddressSecSchnorrPubKey: if addr == nil { return nil, ErrUnsupportedAddress } return payToSchnorrPubKeyScript(addr.ScriptAddress()) } return nil, ErrUnsupportedAddress }