From 4b44ac9c63020cc71aab1f80c6bf28f1b0f5b6a9 Mon Sep 17 00:00:00 2001 From: "dmitry.shakhtarin" Date: Sun, 9 Sep 2018 08:45:56 +0300 Subject: [PATCH] summirizing contract --- .../scala/fluence/hackethberlin/Expr.scala | 32 +++++++++++- .../scala/fluence/hackethberlin/FuncDef.scala | 8 ++- .../hackethberlin/types/PrimitiveType.scala | 3 ++ .../hackethberlin/types/ProductType.scala | 4 +- src/main/scala/fluence/MakeVyperApp.scala | 52 ++++++++++++++++++- src/main/scala/fluence/MyContract.scala | 4 +- 6 files changed, 96 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/fluence/hackethberlin/Expr.scala b/core/src/main/scala/fluence/hackethberlin/Expr.scala index 20ad47d..69e4c2f 100644 --- a/core/src/main/scala/fluence/hackethberlin/Expr.scala +++ b/core/src/main/scala/fluence/hackethberlin/Expr.scala @@ -15,7 +15,7 @@ sealed trait InlineExpr[T] extends Expr[T] with Expr.ToInlineVyper { def :=:(name: Symbol): Free[Expr, Expr.Ref[T]] = Free.liftF[Expr, Expr.Ref[T]](Expr.Assign[T](Expr.Ref[T](name.name, boxedValue), this)) - def :=:(ref: Expr.Ref[T]): Free[Expr, Expr.Ref[T]] = + def :==:(ref: Expr.Ref[T]): Free[Expr, Expr.Ref[T]] = Free.liftF[Expr, Expr.Ref[T]](Expr.Assign[T](ref, this)) } @@ -39,6 +39,15 @@ object Expr { override def toInlineVyper: String = toVyper } + case class Right[R, T]( + op: String, + right: InlineExpr[R], + boxedValue: T + ) extends InlineExpr[T] { + override def toVyper: String = s"$op " + right.toVyper + override def toInlineVyper: String = toVyper + } + case class Assign[T](ref: Ref[T], value: InlineExpr[T]) extends Expr[Ref[T]] { override def boxedValue: Ref[T] = ref @@ -58,6 +67,27 @@ object Expr { def `++`(a: InlineExpr[uint256.type], b: InlineExpr[uint256.type]): InlineExpr[uint256.type] = Infix("+", a, b, uint256) + + def `==`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = + Infix("==", a, b, bool) + + def `+:+`(a: InlineExpr[timestamp.type], b: InlineExpr[timedelta.type]): InlineExpr[timestamp.type] = + Infix("+", a, b, timestamp) + + def `if`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = + Right("if", expr, bool) + + def `not`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = + Right("not", expr, bool) + + def `assertt`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = + Right("assert", expr, bool) + + def `<`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = + Infix("<", a, b, bool) + + def `>`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = + Infix(">", a, b, bool) } object Defs extends Defs diff --git a/core/src/main/scala/fluence/hackethberlin/FuncDef.scala b/core/src/main/scala/fluence/hackethberlin/FuncDef.scala index c4fe4e5..c5032ee 100644 --- a/core/src/main/scala/fluence/hackethberlin/FuncDef.scala +++ b/core/src/main/scala/fluence/hackethberlin/FuncDef.scala @@ -1,12 +1,16 @@ package fluence.hackethberlin -import fluence.hackethberlin.types.{DataVyper, ProductType} +import fluence.hackethberlin.types.{Call, DataVyper, ProductType} import shapeless._ +import BasisConstraint._ import cats.free.Free +import shapeless.ops.hlist.{Mapped, ToList} +import shapeless.ops.record.{Keys, Selector, Values} +import shapeless.tag.@@ class FuncDef[Args <: HList, Ret <: types.Type, Params <: HList]( name: String, - argsDef: ProductType[Args], + val argsDef: ProductType[Args], ret: Ret, body: ProductType[Args] ⇒ Free[Expr, Ret], decorators: Set[Decorator] = Set.empty diff --git a/core/src/main/scala/fluence/hackethberlin/types/PrimitiveType.scala b/core/src/main/scala/fluence/hackethberlin/types/PrimitiveType.scala index da5d9c1..4f09855 100644 --- a/core/src/main/scala/fluence/hackethberlin/types/PrimitiveType.scala +++ b/core/src/main/scala/fluence/hackethberlin/types/PrimitiveType.scala @@ -17,5 +17,8 @@ object PrimitiveType { case object uint256 extends PrimitiveType("uint256") case object decimal extends PrimitiveType("decimal") case object string extends PrimitiveType("string") + case object timestamp extends PrimitiveType("timestamp") + case object wei_value extends PrimitiveType("wei_value") + case object timedelta extends PrimitiveType("timedelta") } } diff --git a/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala b/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala index 82b288e..270244a 100644 --- a/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala +++ b/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala @@ -7,7 +7,9 @@ import shapeless.ops.record.Selector class ProductType[D <: HList](dataDef: D, dv: DataVyper[D]) extends Type { - def ref[T <: Symbol, V <: Type](k: Witness.Aux[T])(implicit selector: Selector.Aux[D, T, V]): InlineExpr[V] = + import fluence.hackethberlin.untag._ + + def ref[T <: Symbol, V <: Type](k: Witness.Aux[T])(implicit selector: Selector.Aux[D, T, V]): Expr.Ref[V] = Expr.Ref[V](k.value.name, selector(dataDef)) // type in type definition somewhere diff --git a/src/main/scala/fluence/MakeVyperApp.scala b/src/main/scala/fluence/MakeVyperApp.scala index ffb62bb..111fba0 100644 --- a/src/main/scala/fluence/MakeVyperApp.scala +++ b/src/main/scala/fluence/MakeVyperApp.scala @@ -4,6 +4,7 @@ import hackethberlin._ import hackethberlin.types._ import shapeless._ import Decorator._ +import cats.free.Free import syntax.singleton._ object MakeVyperApp extends App { @@ -51,7 +52,7 @@ object MakeVyperApp extends App { for { c ← 'c :=: `++`(args.ref('a), args.ref('b)) d ← 'd :=: `++`(args.ref('b), c) - _ ← d :=: c + _ ← d :==: c sum ← `++`(args.ref('a), d).toReturn } yield sum } @@ -68,3 +69,52 @@ object MakeVyperApp extends App { // println(s"MMMMMACRO\n\n ${new MyContract("abc", 123).toAST.toVyper}") } + +object Auction { + val data = ProductType( + ('beneficiary ->> public(address)) :: + ('auction_start ->> public(timestamp)) :: + ('auction_end ->> public(timestamp)) :: + ('highest_bidder ->> `public`(address)) :: + ('highest_bid ->> `public`(wei_value)) :: + ('ended ->> public(bool)) :: HNil + ) + + val beneficiary = data.ref('beneficiary) + val auction_start = data.ref('auction_start) + val auction_end = data.ref('auction_end) + val highest_bid = data.ref('highest_bid) + + val initArgs = ProductType(('_beneficiary ->> address) :: ('_bidding_time ->> timedelta) :: HNil) + + import untag._ + + val _beneficiary = initArgs.ref('_beneficiary) + val _bidding_time = initArgs.ref('_bidding_time) + + println(_beneficiary.getClass) + + val init = `@public` @: initArgs.funcDef( + "__init__", + Void + ) { args ⇒ + for { + _ <- Free.pure(Void) +// _ <- beneficiary :==: _beneficiary +// _ <- auction_start :==: block.timestamp +// _ <- auction_end :==: auction_start `+:+` _bidding_time + } yield Void + } + + + val bid = `@public` @: `@payable` @: ProductType(HNil).funcDef( + "bid", + Void + ) { args ⇒ + for { + _ <- Free.pure(Void) + _ <- `assertt` (block.timestamp `<` auction_end) + _ <- `assertt` (msg.value `>` highest_bid) + } yield Void + } +} \ No newline at end of file diff --git a/src/main/scala/fluence/MyContract.scala b/src/main/scala/fluence/MyContract.scala index a26aa6c..ad356dc 100644 --- a/src/main/scala/fluence/MyContract.scala +++ b/src/main/scala/fluence/MyContract.scala @@ -1,5 +1,5 @@ package fluence import fluence.hackethberlin.ToVyper -@ToVyper -class MyContract(owner: String, friend: Int) {} +//@ToVyper +//class MyContract(owner: String, friend: Int) {}