-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from ergoplatform/develop
Release v4.0.1 (with Sigma v4.0.1 and ergo-wallet v4.0.0)
- Loading branch information
Showing
14 changed files
with
374 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
appkit/src/test/scala/org/ergoplatform/appkit/TxBuilderSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package org.ergoplatform.appkit | ||
|
||
import java.math.BigInteger | ||
import java.util.Arrays | ||
|
||
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks | ||
import org.scalatest.{PropSpec, Matchers} | ||
import sigmastate.eval.CBigInt | ||
import sigmastate.helpers.NegativeTesting | ||
|
||
class TxBuilderSpec extends PropSpec with Matchers | ||
with ScalaCheckDrivenPropertyChecks | ||
with AppkitTesting | ||
with HttpClientTesting | ||
with NegativeTesting { | ||
|
||
def createTestInput(ctx: BlockchainContext): InputBox = { | ||
ctx.newTxBuilder.outBoxBuilder | ||
.value(30000000) | ||
.contract(ctx.compileContract( | ||
ConstantsBuilder.empty(), | ||
"""{ | ||
| val v1 = getVar[Int](1).get | ||
| val v10 = getVar[BigInt](10).get | ||
| sigmaProp(v1.toBigInt == v10) | ||
|}""".stripMargin)) | ||
.build().convertToInputWith( | ||
"f9e5ce5aa0d95f5d54a7bc89c46730d9662397067250aa18a0039631c0f5b809", | ||
0) | ||
} | ||
|
||
property("ContextVar id should be in range") { | ||
for (id <- 0 to Byte.MaxValue) { | ||
ContextVar.of(id.toByte, 10) | ||
} | ||
|
||
def checkFailed(invalidId: Int) = { | ||
assertExceptionThrown( | ||
ContextVar.of(invalidId.toByte, 10), | ||
exceptionLike[IllegalArgumentException]("Context variable id should be in range"), | ||
clue = s"id: $invalidId" | ||
) | ||
} | ||
|
||
for (id <- Byte.MinValue to -1) { | ||
checkFailed(id) | ||
} | ||
} | ||
|
||
property("InputBox support context variables") { | ||
val ergoClient = createMockedErgoClient(MockData(Nil, Nil)) | ||
ergoClient.execute { ctx: BlockchainContext => | ||
val contextVars = Seq( | ||
ContextVar.of(1.toByte, 100), | ||
ContextVar.of(10.toByte, CBigInt(BigInteger.valueOf(100))) | ||
) | ||
val input = createTestInput(ctx) | ||
.withContextVars(contextVars:_*) | ||
val txB = ctx.newTxBuilder() | ||
val output = txB.outBoxBuilder() | ||
.value(15000000) | ||
.contract(ctx.compileContract( | ||
ConstantsBuilder.empty(),"{sigmaProp(true)}")) | ||
.build() | ||
|
||
val changeAddr = Address.fromErgoTree(input.getErgoTree, NetworkType.MAINNET).getErgoAddress | ||
val unsigned = txB.boxesToSpend(Arrays.asList(input)) | ||
.outputs(output) | ||
.fee(1000000) | ||
.sendChangeTo(changeAddr) | ||
.build() | ||
// alice signing bob's box. Does not work here but works in other cases. | ||
val prover = ctx.newProverBuilder().build() | ||
val signed = prover.sign(unsigned) | ||
|
||
// check the signed transaction contains all the context variables | ||
// we attached to the input box | ||
val extensions = signed.getSignedInputs.get(0).getContextVars | ||
contextVars.foreach { cv => | ||
extensions.containsKey(cv.getId) shouldBe true | ||
extensions.get(cv.getId) shouldBe cv.getValue | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
common/src/main/java/org/ergoplatform/appkit/ContextVar.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package org.ergoplatform.appkit; | ||
|
||
import org.bouncycastle.math.ec.ECPoint; | ||
import sigmastate.AvlTreeData; | ||
import sigmastate.Values; | ||
import special.sigma.GroupElement; | ||
|
||
import java.math.BigInteger; | ||
import java.util.Objects; | ||
|
||
/** | ||
* Represents one context variable binding (id -> value), where | ||
* id is in range [0 .. Byte.MaxValue]. | ||
* Can be attached to each input box of the unsigned transaction. | ||
* @see sigmastate.interpreter.ContextExtension | ||
*/ | ||
public class ContextVar { | ||
/** Minimal valid id of a context variable. */ | ||
public static final byte MIN_ID = 0; | ||
|
||
/** Maximal valid id of a context variable. */ | ||
public static final byte MAX_ID = Byte.MAX_VALUE; | ||
|
||
private final byte _id; | ||
private final ErgoValue<?> _value; | ||
|
||
/** | ||
* Construct a new instance | ||
* | ||
* @param id identifier of the variable in range [0 .. Byte.MaxValue]. | ||
* @param value value of the variable | ||
* @see sigmastate.interpreter.ContextExtension | ||
* @see ErgoValue | ||
*/ | ||
public ContextVar(byte id, ErgoValue<?> value) { | ||
if (id < MIN_ID) | ||
throw new IllegalArgumentException(String.format( | ||
"Context variable id should be in range [0 .. $d]: %d", MAX_ID, id)); | ||
_id = id; | ||
_value = value; | ||
} | ||
|
||
/** Returns the id of this variable. */ | ||
public byte getId() { return _id; } | ||
|
||
/** Returns the value of this variable. */ | ||
public ErgoValue<?> getValue() { return _value; } | ||
|
||
@Override | ||
public int hashCode() { | ||
return _value.hashCode() + _id; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == this) return true; // same instance | ||
if (obj instanceof ContextVar) { | ||
ContextVar other = (ContextVar)obj; | ||
return _id == other._id && Objects.equals(_value, other._value); | ||
} | ||
return false; | ||
} | ||
|
||
static public ContextVar of(byte id, byte value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, short value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, int value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, long value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, BigInteger value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, ECPoint value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, GroupElement value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, Values.SigmaBoolean value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, AvlTreeData value) { | ||
return new ContextVar(id, ErgoValue.of(value)); | ||
} | ||
|
||
static public ContextVar of(byte id, byte[] arr) { | ||
return new ContextVar(id, ErgoValue.of(arr)); | ||
} | ||
|
||
static public <T> ContextVar of(byte id, ErgoValue<T> v) { | ||
return new ContextVar(id, v); | ||
} | ||
} |
Oops, something went wrong.