From 631f6260d6b89b9861d69c1740fe13634f4eb2af Mon Sep 17 00:00:00 2001 From: "dmitry.shakhtarin" Date: Sun, 9 Sep 2018 10:15:49 +0300 Subject: [PATCH] auction --- .../scala/fluence/hackethberlin/Expr.scala | 15 ++++--- .../scala/fluence/hackethberlin/FuncDef.scala | 2 +- .../hackethberlin/types/ProductType.scala | 2 + src/main/scala/fluence/MakeVyperApp.scala | 42 +++++++++++++------ 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/core/src/main/scala/fluence/hackethberlin/Expr.scala b/core/src/main/scala/fluence/hackethberlin/Expr.scala index 2b4ea46..74f8f16 100644 --- a/core/src/main/scala/fluence/hackethberlin/Expr.scala +++ b/core/src/main/scala/fluence/hackethberlin/Expr.scala @@ -12,6 +12,8 @@ sealed trait Expr[T] { sealed trait InlineExpr[T] extends Expr[T] with Expr.ToInlineVyper { def toReturn: Free[Expr, T] = Free liftF Expr.Return[T](this) + def liftF: Free[Expr, T] = Free liftF this + def :=:(name: Symbol): Free[Expr, Expr.Ref[T]] = Free.liftF[Expr, Expr.Ref[T]](Expr.Assign[T](Expr.Ref[T](name.name, boxedValue), this)) @@ -55,8 +57,8 @@ object Expr { body: () ⇒ Free[Expr, Void] ) extends InlineExpr[T] { def bodyVyper: String = - body().foldMap(CodeChunk.fromExpr).run._1.toVyper(1) - override def toVyper: String = s"$op " + right.toVyper + s":\n$bodyVyper\n" + body().foldMap(CodeChunk.fromExpr).run._1.toVyper(2) + override def toVyper: String = s"$op " + right.toVyper + s":\n$bodyVyper" override def toInlineVyper: String = toVyper } @@ -83,13 +85,13 @@ object Expr { 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] = + def `+:+`[A <: timestamp.type, B <: timedelta.type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[timestamp.type] = Infix("+", a, b, timestamp) def `if`(expr: InlineExpr[bool.type], body: () ⇒ Free[Expr, Void]): InlineExpr[Void] = - Right("if", expr, Void) + RightBody("if", expr, Void, body) - def `not`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = + def `not`[A <: bool.type](expr: InlineExpr[A]): InlineExpr[bool.type] = Right("not", expr, bool) def `assertt`(expr: InlineExpr[bool.type]): InlineExpr[bool.type] = @@ -98,6 +100,9 @@ object Expr { 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) + def `>>`[A <: Type, B <: Type](a: InlineExpr[A], b: InlineExpr[B]): InlineExpr[bool.type] = Infix(">", a, b, bool) } diff --git a/core/src/main/scala/fluence/hackethberlin/FuncDef.scala b/core/src/main/scala/fluence/hackethberlin/FuncDef.scala index 72d83e0..102a757 100644 --- a/core/src/main/scala/fluence/hackethberlin/FuncDef.scala +++ b/core/src/main/scala/fluence/hackethberlin/FuncDef.scala @@ -52,7 +52,7 @@ object FuncDef { import syntax.singleton._ val send = { - ProductType(('_addr ->> address) :: ('_money ->> wei_value) :: HNil).funcDef( + ProductType(('_addr ->> `public`(address)) :: ('_money ->> `public`(wei_value)) :: HNil).funcDef( "send", Void ) { args ⇒ diff --git a/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala b/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala index c7a60d8..d497df5 100644 --- a/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala +++ b/core/src/main/scala/fluence/hackethberlin/types/ProductType.scala @@ -36,4 +36,6 @@ object ProductType { def apply[D <: HList](dataDef: D)(implicit dv: DataVyper[D]): ProductType[D] = new ProductType[D](dataDef, dv) + + def hNil: ProductType[HNil] = ProductType(HNil) } diff --git a/src/main/scala/fluence/MakeVyperApp.scala b/src/main/scala/fluence/MakeVyperApp.scala index 1020441..e12af31 100644 --- a/src/main/scala/fluence/MakeVyperApp.scala +++ b/src/main/scala/fluence/MakeVyperApp.scala @@ -5,7 +5,6 @@ import hackethberlin.types._ import shapeless._ import Decorator._ import cats.free.Free -import fluence.hackethberlin.Expr.Defs import syntax.singleton._ object MakeVyperApp extends App { @@ -52,6 +51,7 @@ object MakeVyperApp extends App { sumArgs.funcDef("sum", uint256) { args ⇒ for { c ← 'c :=: `++`(args.ref('a), args.ref('b)) + _ ← Free.pure(`++`(args.ref('a), args.ref('b))) d ← 'd :=: `++`(args.ref('b), c) _ ← d :=: c sum ← `++`(args.ref('a), d).toReturn @@ -71,19 +71,21 @@ object MakeVyperApp extends App { // println(s"MMMMMACRO\n\n ${new MyContract("abc", 123).toAST.toVyper}") } -object Auction { +object Auction extends App { import Expr.Defs._ val predef = ProductType( (Symbol("block.timestamp") ->> timestamp) :: - (Symbol("msg.value") ->> uint256) :: + (Symbol("msg.value") ->> wei_value) :: (Symbol("msg.sender") ->> address) :: + (Symbol("True") ->> bool) :: HNil ) val `block.timestamp` = predef.ref(Symbol("block.timestamp")) val `msg.value` = predef.ref(Symbol("msg.value")) val `msg.sender` = predef.ref(Symbol("msg.sender")) + val `True` = predef.ref('True) val data = ProductType( ('beneficiary ->> public(address)) :: @@ -99,14 +101,13 @@ object Auction { val auction_end = data.ref('auction_end) val highest_bid = data.ref('highest_bid) val highest_bidder = data.ref('highest_bidder) + val ended = data.ref('ended) val initArgs = ProductType(('_beneficiary ->> address) :: ('_bidding_time ->> timedelta) :: HNil) val _beneficiary = initArgs.ref('_beneficiary) val _bidding_time = initArgs.ref('_bidding_time) - println(_beneficiary.getClass) - val init = `@public` @: initArgs.funcDef( "__init__", Void @@ -115,27 +116,42 @@ object Auction { _ <- Free.pure(Void) _ <- beneficiary :=: _beneficiary _ <- auction_start :=: `block.timestamp` -// _ <- auction_end :=: `+:+`(auction_start, _bidding_time) + _ <- auction_end :=: `+:+`(auction_start, _bidding_time) } yield Void } val bidIf: () ⇒ Free[Expr, Void] = { () => for { - _ <- Free.pure(Void) -// _ <- FuncDef.send(highest_bidder :: highest_bid :: HNil) + _ <- FuncDef.send(highest_bidder :: highest_bid :: HNil).liftF } yield Void } - /*val bid = `@public` @: `@payable` @: ProductType(HNil: HList).funcDef( + val bid = `@public` @: `@payable` @: ProductType.hNil.funcDef( "bid", Void ) { args ⇒ for { - _ <- `assertt`(`block.timestamp` `<<` auction_end) - _ <- `assertt`(`msg.value` `>>` highest_bid) - _ <- `if`(`not`(highest_bid `:===:` `msg.value`), bidIf) + _ <- `assertt`(`<<`(`block.timestamp`, auction_end)).liftF + _ <- `assertt`(`>>`(`msg.value`, highest_bid)).liftF + _ <- `if`(`not`(`:===:`(highest_bid, `msg.value`)), bidIf).liftF _ <- highest_bidder :=: `msg.sender` _ <- highest_bid :=: `msg.value` } yield Void - }*/ + } + + val end_auction = `@public` @: ProductType.hNil.funcDef( + "end_auction", + Void + ) { args ⇒ + for { + _ <- `assertt`(`>=`(`block.timestamp`, auction_end)).liftF + _ <- `assertt`(`not`(ended)).liftF + _ <- ended :=: `True` + _ <- FuncDef.send(beneficiary :: highest_bid :: HNil).liftF + } yield Void + } + + val contract = new Contract(data :: init :: bid :: end_auction :: HNil) + + println(contract.toVyper) }