Skip to content

Commit

Permalink
rename SingleWallet to KeyContainer
Browse files Browse the repository at this point in the history
  • Loading branch information
fluency03 committed May 8, 2018
1 parent ac4a9fe commit 838d064
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 74 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Please see the full API Documentation on Postman: [blockchain-in-scala](https://

### Summary:

Default hostname and port is `localhost:9090`.

#### root

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ object BlockchainActor {
final case object DeleteBlockchain extends BlockchainMsg
final case object CheckBlockchainValidity extends BlockchainMsg

final case class GetBlockFromChain(hash: String) extends BlockMsg
final case class GetBlockByHash(hash: String) extends BlockMsg
final case class GetBlocksByHashesAndIndices(hashes: Set[String], indices: Set[Int]) extends BlockMsg
final case object GetLastBlock extends BlockMsg
final case class GetTxOfBlock(id: String, hash: String) extends BlockMsg
final case class AppendBlock(block: Block) extends BlockMsg
Expand Down Expand Up @@ -59,7 +60,8 @@ class BlockchainActor extends ActorSupport {
}

private def inCaseOfBlockMsg(msg: BlockMsg): Unit = msg match {
case GetBlockFromChain(hash) => onGetBlockFromChain(hash)
case GetBlockByHash(hash) => onGetBlockByHash(hash)
case GetBlocksByHashesAndIndices(hashes, indices) => onGetBlocksByHashesAndIndices(hashes, indices)
case GetLastBlock => onGetLastBlock()
case GetTxOfBlock(id, hash) => onGetTxOfBlock(id, hash)
case AppendBlock(block) => onAppendBlock(block)
Expand Down Expand Up @@ -108,7 +110,10 @@ class BlockchainActor extends ActorSupport {
* Handlers for each of the BlockMsg.
*/

private def onGetBlockFromChain(hash: String): Unit = sender() ! getBlockFromChain(hash)
private def onGetBlockByHash(hash: String): Unit = sender() ! getBlockByHash(hash)

private def onGetBlocksByHashesAndIndices(hashes: Set[String], indices: Set[Int]): Unit =
sender() ! getBlocksByHashesAndIndices(hashes, indices)

private def onGetLastBlock(): Unit = blockchainOpt match {
case Some(blockchain) => sender() ! blockchain.lastBlock()
Expand All @@ -118,7 +123,7 @@ class BlockchainActor extends ActorSupport {
sender() ! None
}

private def onGetTxOfBlock(id: String, hash: String): Unit = getBlockFromChain(hash) match {
private def onGetTxOfBlock(id: String, hash: String): Unit = getBlockByHash(hash) match {
case Some(block) => sender() ! block.transactions.find(_.id == id)
case None => sender() ! None
}
Expand Down Expand Up @@ -188,7 +193,7 @@ class BlockchainActor extends ActorSupport {
private def onGetBlockFromPool(hash: String): Unit = blockPoolActor forward BlockPoolActor.GetBlock(hash)


private def getBlockFromChain(hash: String): Option[Block] = hashIndexMapping.get(hash) match {
private def getBlockByHash(hash: String): Option[Block] = hashIndexMapping.get(hash) match {
case Some(index) => blockchainOpt match {
case Some(blockchain) => Some(blockchain.chain(index))
case None =>
Expand All @@ -199,4 +204,9 @@ class BlockchainActor extends ActorSupport {
case None => None
}

private def getBlocksByHashesAndIndices(hashes: Set[String], indices: Set[Int]): Set[Block] = {
???
}


}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.github.fluency03.blockchain
package api.actors

import java.security.KeyPair

import akka.actor.Props
import com.github.fluency03.blockchain.api.actors.PeerActor._
import com.github.fluency03.blockchain.core.{Peer, SingleWallet}
import com.github.fluency03.blockchain.core.{Peer, KeyContainer}

import scala.collection.mutable

Expand All @@ -19,12 +17,12 @@ class PeerActor extends ActorSupport {
override def preStart(): Unit = {
log.info("{} started!", this.getClass.getSimpleName)
addWallet()
log.info("Created initial wallet: {}", wallets.head._1)
log.info("Created initial wallet: {}", wallet.head._1)
}
override def postStop(): Unit = log.info("{} stopped!", this.getClass.getSimpleName)

// TODO (Chang): need persistence
val wallets = mutable.Map.empty[String, SingleWallet]
val wallet = mutable.Map.empty[String, KeyContainer]
val others = mutable.Map.empty[String, Peer]

/**
Expand All @@ -35,15 +33,15 @@ class PeerActor extends ActorSupport {
*/

def receive: Receive = {
case GetPublicKeys => sender() ! wallets.values.map(_.address).toSet
case GetPublicKeys => sender() ! wallet.values.map(_.address).toSet
case CreateWallet => sender() ! addWallet()
case _ => unhandled _
}

private def addWallet(): String = {
val newWallet = SingleWallet()
wallets += (newWallet.address -> newWallet)
newWallet.address
val kc = KeyContainer()
wallet += (kc.address -> kc)
kc.address
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,4 @@ package object api {

val PARENT_UP = "../"








}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ trait BlockPoolRoutes extends RoutesSupport {
} ~
path(NEXT_BLOCK) {
post {
parameters('id.as(CsvSeq[String]).?) { idsOpt: Option[Seq[String]] =>
parameters('ids.as(CsvSeq[String]).?) { idsOpt: Option[Seq[String]] =>
entity(as[Input]) { in =>
val maybeNextBlock: Future[Option[Block]] =
(blockPoolActor ? MineAndAddNextBlock(in.content, idsOpt.getOrElse(Seq.empty[String]))).mapTo[Option[Block]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,23 @@ trait BlockchainRoutes extends RoutesSupport {
onSuccess(blockchainDeleted) { respondOnDeletion }
}
} ~
path(BLOCKS) {
get {
parameters('hashes.as(CsvSeq[String]).?, 'indices.as(CsvSeq[Int]).?) {
(hashesOpt: Option[Seq[String]], indicesOpt: Option[Seq[Int]]) =>
val blocks: Future[Set[Block]] = (blockchainActor ?
GetBlocksByHashesAndIndices(
hashesOpt.getOrElse(Seq.empty[String]).toSet,
indicesOpt.getOrElse(Seq.empty[Int]).toSet))
.mapTo[Set[Block]]
rejectEmptyResponse { complete(blocks) }
}
}
} ~
pathPrefix(BLOCK / Segment) { hash =>
pathEnd {
get {
val maybeBlock: Future[Option[Block]] = (blockchainActor ? GetBlockFromChain(hash)).mapTo[Option[Block]]
val maybeBlock: Future[Option[Block]] = (blockchainActor ? GetBlockByHash(hash)).mapTo[Option[Block]]
rejectEmptyResponse { complete(maybeBlock) }
}
} ~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,31 @@ package core

import java.security.KeyPair

import com.github.fluency03.blockchain.core.SingleWallet.balanceOfWallet
import com.github.fluency03.blockchain.core.KeyContainer.balanceOfKey
import com.github.fluency03.blockchain.core.Transaction.signTxIn
import com.github.fluency03.blockchain.crypto.Secp256k1

import scala.collection.mutable

case class SingleWallet() {
case class KeyContainer() {

private[this] val keyPair: KeyPair = Secp256k1.generateKeyPair()

lazy val address: String = keyPair.getPublic.toHex

def balance(uTxOs: mutable.Map[Outpoint, TxOut]): Long = balanceOfWallet(this, uTxOs)
lazy val publicKeyHex: String = keyPair.getPublic.toHex

def balance(uTxOs: mutable.Map[Outpoint, TxOut]): Long = balanceOfKey(this, uTxOs)

def sign(txId: String, txIn: TxIn, uTxOs: mutable.Map[Outpoint, TxOut]): Option[TxIn] =
signTxIn(txId, txIn, keyPair, uTxOs)

}

object SingleWallet {
object KeyContainer {

def balanceOfWallet(wallet: SingleWallet, uTxOs: mutable.Map[Outpoint, TxOut]): Long =
balanceOfAddress(wallet.address, uTxOs)
def balanceOfKey(kc: KeyContainer, uTxOs: mutable.Map[Outpoint, TxOut]): Long =
balanceOfAddress(kc.address, uTxOs)

def balanceOfAddress(address: String, uTxOs: mutable.Map[Outpoint, TxOut]): Long =
uTxOs.values.filter(_.address == address).map(_.amount).sum
Expand Down
41 changes: 41 additions & 0 deletions src/main/scala/com/github/fluency03/blockchain/core/Wallet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.github.fluency03.blockchain.core

trait Wallet {

}



case class RandomWallet() extends Wallet {



}



object RandomWallet {



}




case class SeededWallet() extends Wallet {



}



object SeededWallet {



}



Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,21 @@ object Secp256k1 {
def publicKeyHexToAddress(publicKey: String, networkBytes: String = "00"): String =
Base58.checkEncode(networkBytes.hex2Bytes ++ publicKey.hex2Bytes.toHash160Digest)

/**
* Convert a Public Key to its Base58 Address.
* 0 - Private ECDSA Key
* 1 - Public ECDSA Key
* 2 - SHA-256 hash of 1
* 3 - RIPEMD-160 Hash of 2
* 4 - Adding network bytes to 3
* 5 - SHA-256 hash of 4
* 6 - SHA-256 hash of 5
* 7 - First four bytes of 6
* 8 - Adding 7 at the end of 4
* 9 - Base58 encoding of 8
*/
def publicKeyToAddress(publicKey: PublicKey, networkBytes: String = "00"): String =
Base58.checkEncode(networkBytes.hex2Bytes ++ publicKeyToBytes(publicKey).toHash160Digest)


}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ class BlockchainActorTest extends TestKit(ActorSystem("BlockchainActorTest")) wi
blockchainActor ! GetBlockchain
val blockchain = expectMsgType[Some[Blockchain]].get

blockchainActor ! GetBlockFromChain("somehash")
blockchainActor ! GetBlockByHash("somehash")
expectMsg(None)

val genesis = Block.genesisBlock
blockchainActor ! GetBlockFromChain(genesis.hash)
blockchainActor ! GetBlockByHash(genesis.hash)
expectMsg(Some(genesis))

blockchainActor ! GetLastBlock
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.github.fluency03.blockchain
package core

import com.github.fluency03.blockchain.core.KeyContainer._

import org.scalatest.{FlatSpec, Matchers}

import scala.collection.mutable

class KeyContainerTest extends FlatSpec with Matchers {

"balanceOfKey" should "obtain the balance of a Key based on UTXOs." in {
val kc = KeyContainer()
val uTxOs: mutable.Map[Outpoint, TxOut] = mutable.Map.empty[Outpoint, TxOut]

balanceOfKey(kc, uTxOs) shouldEqual 0
kc.balance(uTxOs) shouldEqual 0

uTxOs += (Outpoint("def0", 0) -> TxOut(kc.address, 40))
uTxOs += (Outpoint("def0", 1) -> TxOut("abc4", 40))

balanceOfKey(kc, uTxOs) shouldEqual 40
kc.balance(uTxOs) shouldEqual 40
}

"KeyContainer" should "be able to sign a TxIn." in {
val kc = KeyContainer()
val id = "".toSha256
val txIn = TxIn(Outpoint("def0", 0), "abc")
val uTxOs: mutable.Map[Outpoint, TxOut] = mutable.Map.empty[Outpoint, TxOut]

val signedTxIn0 = kc.sign(id, txIn, uTxOs)
signedTxIn0 shouldEqual None

uTxOs += (Outpoint("def0", 0) -> TxOut(kc.address, 40))
uTxOs += (Outpoint("def0", 1) -> TxOut("abc4", 40))

val signedTxIn = kc.sign(id, txIn, uTxOs)
signedTxIn shouldEqual Some(TxIn(Outpoint("def0", 0), signedTxIn.get.signature))
}


}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.fluency03.blockchain.core

import org.scalatest.{FlatSpec, Matchers}

class WalletTest extends FlatSpec with Matchers {

"Wallet" should "do something." in {

}

}

0 comments on commit 838d064

Please sign in to comment.