Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2SH address to use 126 as scriptId #919

Merged
merged 1 commit into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package org.ergoplatform

import scorex.utils.Ints
import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix
import scorex.crypto.hash.{Digest32, Blake2b256}
import scorex.crypto.hash.{Blake2b256, Digest32}
import scorex.util.encode.Base58
import sigmastate.Values._
import sigmastate._
import sigmastate.crypto.DLogProtocol.{ProveDlogProp, ProveDlog}
import sigmastate.crypto.DLogProtocol.{ProveDlog, ProveDlogProp}
import sigmastate.exceptions.SigmaException
import sigmastate.serialization._
import sigmastate.utxo.{DeserializeContext, Slice}
Expand Down Expand Up @@ -128,7 +128,9 @@ object P2PKAddress {
}
}

/** Implementation of pay-to-script-hash [[ErgoAddress]]. */
/** Implementation of pay-to-script-hash [[ErgoAddress]].
* @param scriptHash first 192 bits of the Blake2b256 hash of serialized script bytes
*/
class Pay2SHAddress(val scriptHash: Array[Byte])(implicit val encoder: ErgoAddressEncoder) extends ErgoAddress {
override val addressTypePrefix: Byte = Pay2SHAddress.addressTypePrefix

Expand All @@ -141,12 +143,12 @@ class Pay2SHAddress(val scriptHash: Array[Byte])(implicit val encoder: ErgoAddre
/** The proposition which checks that `contextVar(scriptId)` has original script
* (whose hash equals to this [[scriptHash]]) which evaluates to true.
*
* Assumes the context variable is accessed as `getVar[Coll[Byte]](1).get`
* Assumes the context variable is accessed as `getVar[Coll[Byte]](126).get`
* and contains serialized original script bytes.
*
* NOTE: This script is not stored in [[contentBytes]] of the address.
* NOTE: This `script` field is not stored in [[contentBytes]] of the address.
* So the address doesn't depend on this script which means this specific script can be
* changed without breaking the addresses.
* changed without breaking the existing p2sh addresses.
*
* NOTE: The ErgoTree is created without segregation of the constants.
*
Expand All @@ -158,7 +160,7 @@ class Pay2SHAddress(val scriptHash: Array[Byte])(implicit val encoder: ErgoAddre
override val script = {
val hashEquals = EQ(
Slice(CalcBlake2b256(GetVarByteArray(scriptId).get), IntConstant(0), IntConstant(24)),
scriptHash
ByteArrayConstant(scriptHash)
)
val scriptIsCorrect = DeserializeContext(scriptId, SSigmaProp)
ErgoTree.withoutSegregation(SigmaAnd(hashEquals.toSigmaProp, scriptIsCorrect))
Expand All @@ -176,9 +178,10 @@ class Pay2SHAddress(val scriptHash: Array[Byte])(implicit val encoder: ErgoAddre

object Pay2SHAddress {
/** An id of the context variable used in pay-to-script-hash address script.
* Note, value 127 is used for strage rent in Ergo node, see org.ergoplatform.wallet.interpreter.ErgoInterpreter
* @see [[Pay2SHAddress.script]]
*/
val scriptId = 1: Byte
val scriptId = 126: Byte

/** Value added to the prefix byte in the serialized bytes of an encoded P2SH address.
* @see [[ErgoAddressEncoder.toString]]
Expand Down Expand Up @@ -300,7 +303,7 @@ case class ErgoAddressEncoder(networkPrefix: NetworkPrefix) {
new P2PKAddress(ProveDlog(p), contentBytes)
case Pay2SHAddress.addressTypePrefix =>
if (contentBytes.length != 24) { //192-bits hash used
throw new Exception(s"Improper content in P2SH script: $addrBase58Str")
throw new Exception(s"Invalid length of the hash bytes in P2SH address: $addrBase58Str")
}
new Pay2SHAddress(contentBytes)
case Pay2SAddress.addressTypePrefix =>
Expand Down Expand Up @@ -328,7 +331,8 @@ case class ErgoAddressEncoder(networkPrefix: NetworkPrefix) {
}

/** Converts the given [[ErgoTree]] to the corresponding [[ErgoAddress]].
* It is inverse of [[ErgoAddress.script]] such that `fromProposition(addr.script) == addr`
* It is inverse of [[ErgoAddress.script]] such that
* `ErgoAddressEncoder.fromProposition(addr.script) == addr`
*
* @return Failure(ex) if the `proposition` cannot be converted to any type of address.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class ErgoAddressSpecification extends SigmaDslTesting

assertExceptionThrown(
ergoAddressEncoder.fromString(addrStr).getOrThrow,
t => t.getMessage.contains("Improper content in P2SH script: 41fKjb7zWNw")
t => t.getMessage.contains("Invalid length of the hash bytes in P2SH address: 41fKjb7zWNw")
)
}

Expand Down Expand Up @@ -228,7 +228,7 @@ class ErgoAddressSpecification extends SigmaDslTesting
}

def testPay2SHAddress(address: Pay2SHAddress, scriptBytes: Array[Byte]) = {
val scriptId = 1.toByte
val scriptId = Pay2SHAddress.scriptId
val boxToSpend = testBox(10, address.script, creationHeight = 5)
val ctx = ErgoLikeContextTesting.dummy(boxToSpend, activatedVersionInTests)
.withExtension(ContextExtension(Seq(
Expand Down Expand Up @@ -271,7 +271,7 @@ class ErgoAddressSpecification extends SigmaDslTesting
res
}

val scriptVarId = 1.toByte
val scriptVarId = Pay2SHAddress.scriptId
val script = "{ 1 < 2 }"
val prop = compile(Map.empty, script).asBoolValue.toSigmaProp
val scriptBytes = ValueSerializer.serialize(prop)
Expand Down
Loading