You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

81 lines
2.4 KiB

package com.xsn.explorer.models
import com.xsn.explorer.models.values.{Address, TransactionId}
import enumeratum._
import play.api.libs.json.{Json, Writes}
import scala.util.Try
case class TPoSContract(
id: TPoSContract.Id,
details: TPoSContract.Details,
time: Long,
state: TPoSContract.State) {
val txid: TransactionId = id.txid
}
object TPoSContract {
case class Id(txid: TransactionId, index: Int)
class Commission private (val int: Int) extends AnyVal
object Commission {
val range = 1 until 100
def from(int: Int): Option[Commission] = {
if (range contains int) Some(new Commission(int))
else None
}
}
case class Details(owner: Address, merchant: Address, merchantCommission: Commission)
object Details {
/**
* Try to get the contract details from the output script ASM.
*
* expected format:
* - "OP_RETURN [hex_encoded_owner_address] [hex_encoded_merchant_address] [owner_commission] [signature]
*
* example:
* - "OP_RETURN 5869337351664d51737932437a4d5a54726e4b573648464770315671465468644c77 58794a4338786e664672484e634d696e68366778755052595939484361593944416f 99"
*/
def fromOutputScriptASM(asm: String): Option[Details] = {
val parts = asm.split(" ").toList
parts match {
case op :: owner :: merchant :: commission :: signature :: Nil if op == "OP_RETURN" =>
for {
ownerAddress <- Address.fromHex(owner)
merchantAddress <- Address.fromHex(merchant)
ownerCommission <- Try(commission.toInt).toOption
merchantCommission <- TPoSContract.Commission.from(100 - ownerCommission)
} yield Details(owner = ownerAddress, merchant = merchantAddress, merchantCommission = merchantCommission)
case _ => None
}
}
}
sealed abstract class State(override val entryName: String) extends EnumEntry
object State extends Enum[State] {
val values = findValues
final case object Active extends State("ACTIVE")
final case object Closed extends State("CLOSED")
}
implicit val writes: Writes[TPoSContract] = (obj: TPoSContract) => {
Json.obj(
"txid" -> obj.id.txid,
"index" -> obj.id.index,
"owner" -> obj.details.owner,
"merchant" -> obj.details.merchant,
"merchantCommission" -> obj.details.merchantCommission.int,
"time" -> obj.time,
"state" -> obj.state.entryName
)
}
}