mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 06:57:51 +01:00
Merge pull request #110 from Christewart/address_refactor
Address refactor
This commit is contained in:
commit
368826ccbf
6 changed files with 91 additions and 68 deletions
|
@ -1,16 +1,22 @@
|
||||||
package org.bitcoins.core.config
|
package org.bitcoins.core.config
|
||||||
|
|
||||||
|
import org.bitcoins.core.protocol.blockchain._
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 7/27/15.
|
* Created by chris on 7/27/15.
|
||||||
*/
|
*/
|
||||||
sealed abstract class NetworkParameters {
|
sealed abstract class NetworkParameters {
|
||||||
def p2pkhNetworkByte : Byte
|
/** The parameters of the blockchain we are connecting to */
|
||||||
def p2shNetworkByte : Byte
|
def chainParams: ChainParams
|
||||||
def privateKey : Byte
|
|
||||||
|
def p2pkhNetworkByte: Byte = chainParams.base58Prefix(Base58Type.PubKeyAddress).head
|
||||||
|
def p2shNetworkByte: Byte = chainParams.base58Prefix(Base58Type.ScriptAddress).head
|
||||||
|
def privateKey: Byte = chainParams.base58Prefix(Base58Type.SecretKey).head
|
||||||
|
|
||||||
def port : Int
|
def port : Int
|
||||||
def rpcPort: Int
|
def rpcPort: Int
|
||||||
def name: String
|
def name: String = chainParams.networkId
|
||||||
/** The seeds used to bootstrap the network */
|
/** The seeds used to bootstrap the network */
|
||||||
def dnsSeeds : Seq[String]
|
def dnsSeeds : Seq[String]
|
||||||
|
|
||||||
|
@ -23,13 +29,17 @@ sealed abstract class NetworkParameters {
|
||||||
def magicBytes : Seq[Byte]
|
def magicBytes : Seq[Byte]
|
||||||
|
|
||||||
/** In bitcoin, the network recaculates the difficulty for the network every 2016 blocks */
|
/** In bitcoin, the network recaculates the difficulty for the network every 2016 blocks */
|
||||||
def difficultyChangeThreshold = 2016
|
def difficultyChangeThreshold: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MainNet extends NetworkParameters {
|
sealed abstract class BitcoinNetwork extends NetworkParameters {
|
||||||
override def p2pkhNetworkByte = 0x00
|
override def difficultyChangeThreshold: Int = 2016
|
||||||
override def p2shNetworkByte = 0x05
|
|
||||||
override def privateKey = 0x80.toByte
|
override def chainParams: BitcoinChainParams
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed abstract class MainNet extends BitcoinNetwork {
|
||||||
|
override def chainParams = MainNetChainParams
|
||||||
override def port = 8333
|
override def port = 8333
|
||||||
override def rpcPort = 8332
|
override def rpcPort = 8332
|
||||||
//mainnet doesn't need to be specified like testnet or regtest
|
//mainnet doesn't need to be specified like testnet or regtest
|
||||||
|
@ -38,34 +48,52 @@ trait MainNet extends NetworkParameters {
|
||||||
"seed.bitcoinstats.com","bitseed.xf2.org","seed.bitcoin.jonasschnelli.ch")
|
"seed.bitcoinstats.com","bitseed.xf2.org","seed.bitcoin.jonasschnelli.ch")
|
||||||
|
|
||||||
override def magicBytes = Seq(0xf9.toByte, 0xbe.toByte, 0xb4.toByte, 0xd9.toByte)
|
override def magicBytes = Seq(0xf9.toByte, 0xbe.toByte, 0xb4.toByte, 0xd9.toByte)
|
||||||
|
|
||||||
|
override def difficultyChangeThreshold: Int = 2016
|
||||||
}
|
}
|
||||||
|
|
||||||
object MainNet extends MainNet
|
object MainNet extends MainNet
|
||||||
|
|
||||||
trait TestNet3 extends NetworkParameters {
|
sealed abstract class TestNet3 extends NetworkParameters {
|
||||||
override def p2pkhNetworkByte = 0x6F
|
override def chainParams = TestNetChainParams
|
||||||
override def p2shNetworkByte = 0xC4.toByte
|
|
||||||
override def privateKey = 0xEF.toByte
|
|
||||||
override def port = 18333
|
override def port = 18333
|
||||||
override def rpcPort = 18332
|
override def rpcPort = 18332
|
||||||
override def name = "testnet"
|
|
||||||
override def dnsSeeds = Seq("testnet-seed.bitcoin.petertodd.org",
|
override def dnsSeeds = Seq("testnet-seed.bitcoin.petertodd.org",
|
||||||
"testnet-seed.bluematt.me","testnet-seed.bitcoin.schildbach.de")
|
"testnet-seed.bluematt.me","testnet-seed.bitcoin.schildbach.de")
|
||||||
override def magicBytes = Seq(0x0b.toByte, 0x11.toByte, 0x09.toByte, 0x07.toByte)
|
override def magicBytes = Seq(0x0b.toByte, 0x11.toByte, 0x09.toByte, 0x07.toByte)
|
||||||
|
|
||||||
|
override def difficultyChangeThreshold: Int = 2016
|
||||||
}
|
}
|
||||||
|
|
||||||
object TestNet3 extends TestNet3
|
object TestNet3 extends TestNet3
|
||||||
|
|
||||||
trait RegTest extends NetworkParameters {
|
sealed abstract class RegTest extends NetworkParameters {
|
||||||
override def p2pkhNetworkByte = TestNet3.p2pkhNetworkByte
|
override def chainParams: ChainParams = RegTestNetChainParams
|
||||||
override def p2shNetworkByte = TestNet3.p2shNetworkByte
|
|
||||||
override def privateKey = TestNet3.privateKey
|
|
||||||
override def port = 18444
|
override def port = 18444
|
||||||
override def rpcPort = TestNet3.rpcPort
|
override def rpcPort = TestNet3.rpcPort
|
||||||
override def name = "regtest"
|
|
||||||
override def dnsSeeds = Nil
|
override def dnsSeeds = Nil
|
||||||
override def magicBytes = Seq(0xfa.toByte, 0xbf.toByte, 0xb5.toByte, 0xda.toByte)
|
override def magicBytes = Seq(0xfa.toByte, 0xbf.toByte, 0xb5.toByte, 0xda.toByte)
|
||||||
|
override def difficultyChangeThreshold: Int = 2016
|
||||||
}
|
}
|
||||||
|
|
||||||
object RegTest extends RegTest
|
object RegTest extends RegTest
|
||||||
|
|
||||||
|
|
||||||
|
object Networks {
|
||||||
|
val knownNetworks: Seq[NetworkParameters] = Seq(MainNet, TestNet3, RegTest)
|
||||||
|
val secretKeyBytes = knownNetworks.map(_.privateKey)
|
||||||
|
val p2pkhNetworkBytes = knownNetworks.map(_.p2pkhNetworkByte)
|
||||||
|
val p2shNetworkBytes = knownNetworks.map(_.p2shNetworkByte)
|
||||||
|
|
||||||
|
def byteToNetwork: Map[Byte, NetworkParameters] = Map(
|
||||||
|
MainNet.p2shNetworkByte -> MainNet,
|
||||||
|
MainNet.p2pkhNetworkByte -> MainNet,
|
||||||
|
MainNet.privateKey -> MainNet,
|
||||||
|
|
||||||
|
TestNet3.p2pkhNetworkByte -> TestNet3,
|
||||||
|
TestNet3.p2shNetworkByte -> TestNet3,
|
||||||
|
TestNet3.privateKey -> TestNet3
|
||||||
|
|
||||||
|
//ommitting regtest as it has the same network bytes as testnet3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -4,9 +4,8 @@ import java.math.BigInteger
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
|
||||||
import org.bitcoin.NativeSecp256k1
|
import org.bitcoin.NativeSecp256k1
|
||||||
import org.bitcoins.core.config.{MainNet, NetworkParameters, TestNet3}
|
import org.bitcoins.core.config.{NetworkParameters, Networks}
|
||||||
import org.bitcoins.core.protocol.NetworkElement
|
import org.bitcoins.core.protocol.NetworkElement
|
||||||
import org.bitcoins.core.protocol.blockchain.{MainNetChainParams, SecretKey, TestNetChainParams}
|
|
||||||
import org.bitcoins.core.util.{BitcoinSUtil, _}
|
import org.bitcoins.core.util.{BitcoinSUtil, _}
|
||||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair
|
import org.spongycastle.crypto.AsymmetricCipherKeyPair
|
||||||
import org.spongycastle.crypto.digests.SHA256Digest
|
import org.spongycastle.crypto.digests.SHA256Digest
|
||||||
|
@ -155,8 +154,7 @@ object ECPrivateKey extends Factory[ECPrivateKey] {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def isCompressed(bytes : Seq[Byte]): Boolean = {
|
def isCompressed(bytes : Seq[Byte]): Boolean = {
|
||||||
val validCompressedBytes: Seq[Byte] =
|
val validCompressedBytes: Seq[Byte] = Networks.secretKeyBytes
|
||||||
MainNetChainParams.base58Prefix(SecretKey) ++ TestNetChainParams.base58Prefixes(SecretKey)
|
|
||||||
val validCompressedBytesInHex: Seq[String] = validCompressedBytes.map(byte => BitcoinSUtil.encodeHex(byte))
|
val validCompressedBytesInHex: Seq[String] = validCompressedBytes.map(byte => BitcoinSUtil.encodeHex(byte))
|
||||||
val firstByteHex = BitcoinSUtil.encodeHex(bytes.head)
|
val firstByteHex = BitcoinSUtil.encodeHex(bytes.head)
|
||||||
if (validCompressedBytesInHex.contains(firstByteHex)) bytes(bytes.length - 5) == 0x01.toByte
|
if (validCompressedBytesInHex.contains(firstByteHex)) bytes(bytes.length - 5) == 0x01.toByte
|
||||||
|
@ -199,11 +197,7 @@ object ECPrivateKey extends Factory[ECPrivateKey] {
|
||||||
val decoded = Base58.decodeCheck(wif)
|
val decoded = Base58.decodeCheck(wif)
|
||||||
decoded.map { bytes =>
|
decoded.map { bytes =>
|
||||||
val b = bytes.head
|
val b = bytes.head
|
||||||
if (b == TestNetChainParams.base58Prefixes(SecretKey).head) {
|
Networks.byteToNetwork(b)
|
||||||
TestNet3
|
|
||||||
} else if (b == MainNetChainParams.base58Prefixes(SecretKey).head) {
|
|
||||||
MainNet
|
|
||||||
} else throw new IllegalArgumentException("Cannot match wif private key with a network, prefix was: " + BitcoinSUtil.encodeHex(b))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,8 +321,7 @@ object P2PKHAddress {
|
||||||
decodeCheckP2PKH match {
|
decodeCheckP2PKH match {
|
||||||
case Success(bytes) =>
|
case Success(bytes) =>
|
||||||
val firstByte = bytes.head
|
val firstByte = bytes.head
|
||||||
(firstByte == MainNet.p2pkhNetworkByte || firstByte == TestNet3.p2pkhNetworkByte ||
|
Networks.p2pkhNetworkBytes.contains(firstByte) && bytes.size == 21
|
||||||
firstByte == RegTest.p2pkhNetworkByte) && bytes.size == 21
|
|
||||||
case Failure(exception) => false
|
case Failure(exception) => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,9 +356,7 @@ object P2SHAddress {
|
||||||
decodeCheckP2SH match {
|
decodeCheckP2SH match {
|
||||||
case Success(bytes) =>
|
case Success(bytes) =>
|
||||||
val firstByte = bytes.head
|
val firstByte = bytes.head
|
||||||
((firstByte == MainNet.p2shNetworkByte || firstByte == TestNet3.p2shNetworkByte ||
|
Networks.p2shNetworkBytes.contains(firstByte) && bytes.size == 21
|
||||||
RegTest.p2shNetworkByte == firstByte)
|
|
||||||
&& bytes.size == 21)
|
|
||||||
case Failure(_) => false
|
case Failure(_) => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
package org.bitcoins.core.protocol.blockchain
|
package org.bitcoins.core.protocol.blockchain
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
import org.bitcoins.core.consensus.Merkle
|
import org.bitcoins.core.consensus.Merkle
|
||||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||||
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
||||||
import org.bitcoins.core.number.{Int64, UInt32, UInt64}
|
import org.bitcoins.core.number.{Int64, UInt32}
|
||||||
import org.bitcoins.core.protocol.CompactSizeUInt
|
|
||||||
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
|
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
|
||||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionConstants, TransactionInput, TransactionOutput}
|
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionConstants, TransactionInput, TransactionOutput}
|
||||||
import org.bitcoins.core.script.constant.{BytesToPushOntoStack, ScriptConstant, ScriptNumber}
|
import org.bitcoins.core.script.constant.{BytesToPushOntoStack, ScriptConstant, ScriptNumber}
|
||||||
import org.bitcoins.core.script.crypto.OP_CHECKSIG
|
import org.bitcoins.core.script.crypto.OP_CHECKSIG
|
||||||
import org.bitcoins.core.util.BitcoinSUtil
|
import org.bitcoins.core.util.{BitcoinSUtil, BitcoinScriptUtil}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 5/22/16.
|
* Created by chris on 5/22/16.
|
||||||
|
@ -21,7 +22,7 @@ import org.bitcoins.core.util.BitcoinSUtil
|
||||||
* Mimics this C++ interface
|
* Mimics this C++ interface
|
||||||
* https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.h#L42
|
* https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.h#L42
|
||||||
*/
|
*/
|
||||||
sealed trait ChainParams {
|
sealed abstract class ChainParams {
|
||||||
|
|
||||||
/** Return the BIP70 network string ([[MainNetChainParams]], [[TestNetChainParams]] or [[RegTestNetChainParams]].) */
|
/** Return the BIP70 network string ([[MainNetChainParams]], [[TestNetChainParams]] or [[RegTestNetChainParams]].) */
|
||||||
def networkId : String
|
def networkId : String
|
||||||
|
@ -31,7 +32,7 @@ sealed trait ChainParams {
|
||||||
|
|
||||||
/** Filter transactions that do not match well-defined patterns
|
/** Filter transactions that do not match well-defined patterns
|
||||||
* inside of [[org.bitcoins.core.policy.Policy]]. */
|
* inside of [[org.bitcoins.core.policy.Policy]]. */
|
||||||
def requireStandardTransaction : Boolean
|
def requireStandardTransaction : Boolean = true
|
||||||
|
|
||||||
/** Takes in a [[Base58Type]] and returns its base58 prefix. */
|
/** Takes in a [[Base58Type]] and returns its base58 prefix. */
|
||||||
def base58Prefix(base58 : Base58Type) : Seq[Byte] = base58Prefixes(base58)
|
def base58Prefix(base58 : Base58Type) : Seq[Byte] = base58Prefixes(base58)
|
||||||
|
@ -70,72 +71,72 @@ sealed trait ChainParams {
|
||||||
*/
|
*/
|
||||||
def createGenesisBlock(timestamp : String, scriptPubKey : ScriptPubKey, time : UInt32, nonce : UInt32, nBits : UInt32,
|
def createGenesisBlock(timestamp : String, scriptPubKey : ScriptPubKey, time : UInt32, nonce : UInt32, nBits : UInt32,
|
||||||
version : UInt32, amount : CurrencyUnit) : Block = {
|
version : UInt32, amount : CurrencyUnit) : Block = {
|
||||||
val timestampHex = timestamp.toCharArray.map(_.toByte)
|
val timestampBytes = timestamp.getBytes(StandardCharsets.UTF_8)
|
||||||
//see https://bitcoin.stackexchange.com/questions/13122/scriptsig-coinbase-structure-of-the-genesis-block
|
//see https://bitcoin.stackexchange.com/questions/13122/scriptsig-coinbase-structure-of-the-genesis-block
|
||||||
//for a full breakdown of the genesis block & its script signature
|
//for a full breakdown of the genesis block & its script signature
|
||||||
|
val const = ScriptConstant(timestampBytes)
|
||||||
val scriptSignature = ScriptSignature.fromAsm(Seq(BytesToPushOntoStack(4), ScriptNumber(486604799),
|
val scriptSignature = ScriptSignature.fromAsm(Seq(BytesToPushOntoStack(4), ScriptNumber(486604799),
|
||||||
BytesToPushOntoStack(1), ScriptNumber(4), BytesToPushOntoStack(69), ScriptConstant(timestampHex)))
|
BytesToPushOntoStack(1), ScriptNumber(4)) ++ BitcoinScriptUtil.calculatePushOp(const) ++ Seq(const))
|
||||||
val input = TransactionInput(scriptSignature)
|
val input = TransactionInput(scriptSignature)
|
||||||
val output = TransactionOutput(amount,scriptPubKey)
|
val output = TransactionOutput(amount,scriptPubKey)
|
||||||
val tx = Transaction(TransactionConstants.version,Seq(input), Seq(output), TransactionConstants.lockTime)
|
val tx = Transaction(TransactionConstants.version,Seq(input), Seq(output), TransactionConstants.lockTime)
|
||||||
val prevBlockHash = DoubleSha256Digest("0000000000000000000000000000000000000000000000000000000000000000")
|
val prevBlockHash = DoubleSha256Digest("0000000000000000000000000000000000000000000000000000000000000000")
|
||||||
val merkleRootHash = Merkle.computeMerkleRoot(Seq(tx))
|
val merkleRootHash = Merkle.computeMerkleRoot(Seq(tx))
|
||||||
val genesisBlockHeader = BlockHeader(version,prevBlockHash,merkleRootHash,time,nBits,nonce)
|
val genesisBlockHeader = BlockHeader(version,prevBlockHash,merkleRootHash,time,nBits,nonce)
|
||||||
val genesisBlock = Block(genesisBlockHeader,CompactSizeUInt(UInt64.one,1),Seq(tx))
|
val genesisBlock = Block(genesisBlockHeader,Seq(tx))
|
||||||
genesisBlock
|
genesisBlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed abstract class BitcoinChainParams extends ChainParams
|
||||||
/** The Main Network parameters. */
|
/** The Main Network parameters. */
|
||||||
object MainNetChainParams extends ChainParams {
|
object MainNetChainParams extends BitcoinChainParams {
|
||||||
|
|
||||||
override def networkId = "main"
|
override def networkId = "main"
|
||||||
|
|
||||||
override def genesisBlock : Block = createGenesisBlock(UInt32(1231006505), UInt32(2083236893), UInt32(0x1d00ffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
override def genesisBlock : Block = createGenesisBlock(UInt32(1231006505), UInt32(2083236893), UInt32(0x1d00ffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
||||||
|
|
||||||
override def requireStandardTransaction : Boolean = true
|
|
||||||
|
|
||||||
override def base58Prefixes : Map[Base58Type,Seq[Byte]] = Map(
|
override def base58Prefixes : Map[Base58Type,Seq[Byte]] = Map(
|
||||||
PubKeyAddress -> BitcoinSUtil.decodeHex("00"),
|
Base58Type.PubKeyAddress -> BitcoinSUtil.decodeHex("00"),
|
||||||
ScriptAddress -> BitcoinSUtil.decodeHex("05"),
|
Base58Type.ScriptAddress -> BitcoinSUtil.decodeHex("05"),
|
||||||
SecretKey -> BitcoinSUtil.decodeHex("80"),
|
Base58Type.SecretKey -> BitcoinSUtil.decodeHex("80"),
|
||||||
ExtPublicKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("88"),
|
Base58Type.ExtPublicKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("88"),
|
||||||
BitcoinSUtil.hexToByte("b2"), BitcoinSUtil.hexToByte("1e")),
|
BitcoinSUtil.hexToByte("b2"), BitcoinSUtil.hexToByte("1e")),
|
||||||
ExtSecretKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("88"),
|
Base58Type.ExtSecretKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("88"),
|
||||||
BitcoinSUtil.hexToByte("ad"), BitcoinSUtil.hexToByte("e4")))
|
BitcoinSUtil.hexToByte("ad"), BitcoinSUtil.hexToByte("e4")))
|
||||||
}
|
}
|
||||||
|
|
||||||
object TestNetChainParams extends ChainParams {
|
object TestNetChainParams extends BitcoinChainParams {
|
||||||
|
|
||||||
override def networkId = "test"
|
override def networkId = "test"
|
||||||
|
|
||||||
override def genesisBlock : Block = createGenesisBlock(UInt32(1296688602), UInt32(414098458), UInt32(0x1d00ffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
override def genesisBlock : Block = createGenesisBlock(UInt32(1296688602), UInt32(414098458), UInt32(0x1d00ffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
||||||
|
|
||||||
override def requireStandardTransaction : Boolean = true
|
|
||||||
|
|
||||||
override def base58Prefixes : Map[Base58Type,Seq[Byte]] = Map(
|
override def base58Prefixes : Map[Base58Type,Seq[Byte]] = Map(
|
||||||
PubKeyAddress -> BitcoinSUtil.decodeHex("6f"),
|
Base58Type.PubKeyAddress -> BitcoinSUtil.decodeHex("6f"),
|
||||||
ScriptAddress -> BitcoinSUtil.decodeHex("c4"),
|
Base58Type.ScriptAddress -> BitcoinSUtil.decodeHex("c4"),
|
||||||
SecretKey -> BitcoinSUtil.decodeHex("ef"),
|
Base58Type.SecretKey -> BitcoinSUtil.decodeHex("ef"),
|
||||||
ExtPublicKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("35"),
|
Base58Type.ExtPublicKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("35"),
|
||||||
BitcoinSUtil.hexToByte("87"), BitcoinSUtil.hexToByte("cf")),
|
BitcoinSUtil.hexToByte("87"), BitcoinSUtil.hexToByte("cf")),
|
||||||
ExtSecretKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("35"),
|
Base58Type.ExtSecretKey -> Seq(BitcoinSUtil.hexToByte("04"), BitcoinSUtil.hexToByte("35"),
|
||||||
BitcoinSUtil.hexToByte("83"), BitcoinSUtil.hexToByte("94")))
|
BitcoinSUtil.hexToByte("83"), BitcoinSUtil.hexToByte("94")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object RegTestNetChainParams extends ChainParams {
|
object RegTestNetChainParams extends BitcoinChainParams {
|
||||||
override def networkId = "regtest"
|
override def networkId = "regtest"
|
||||||
override def genesisBlock : Block = createGenesisBlock(UInt32(1296688602), UInt32(2), UInt32(0x207fffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
override def genesisBlock : Block = createGenesisBlock(UInt32(1296688602), UInt32(2), UInt32(0x207fffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
||||||
override def requireStandardTransaction : Boolean = TestNetChainParams.requireStandardTransaction
|
|
||||||
override def base58Prefixes : Map[Base58Type, Seq[Byte]] = TestNetChainParams.base58Prefixes
|
override def base58Prefixes : Map[Base58Type, Seq[Byte]] = TestNetChainParams.base58Prefixes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sealed trait Base58Type
|
|
||||||
case object PubKeyAddress extends Base58Type
|
sealed abstract class Base58Type
|
||||||
case object ScriptAddress extends Base58Type
|
object Base58Type {
|
||||||
case object SecretKey extends Base58Type
|
case object PubKeyAddress extends Base58Type
|
||||||
case object ExtPublicKey extends Base58Type
|
case object ScriptAddress extends Base58Type
|
||||||
case object ExtSecretKey extends Base58Type
|
case object SecretKey extends Base58Type
|
||||||
|
case object ExtPublicKey extends Base58Type
|
||||||
|
case object ExtSecretKey extends Base58Type
|
||||||
|
}
|
|
@ -10,11 +10,11 @@ import scala.util.{Failure, Success, Try}
|
||||||
* Created by chris on 5/16/16.
|
* Created by chris on 5/16/16.
|
||||||
* source of values: https://en.bitcoin.it/wiki/Base58Check_encoding
|
* source of values: https://en.bitcoin.it/wiki/Base58Check_encoding
|
||||||
*/
|
*/
|
||||||
trait Base58 extends BitcoinSLogger {
|
sealed abstract class Base58 {
|
||||||
|
import Base58Type._
|
||||||
val base58Characters = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
val base58Characters = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||||
val base58Pairs = base58Characters.zipWithIndex.toMap
|
val base58Pairs = base58Characters.zipWithIndex.toMap
|
||||||
|
private val logger = BitcoinSLogger.logger
|
||||||
/** Verifies a given [[Base58Type]] string against its checksum (last 4 decoded bytes). */
|
/** Verifies a given [[Base58Type]] string against its checksum (last 4 decoded bytes). */
|
||||||
def decodeCheck(input: String) : Try[Seq[Byte]] = {
|
def decodeCheck(input: String) : Try[Seq[Byte]] = {
|
||||||
val decoded : Seq[Byte] = decode(input)
|
val decoded : Seq[Byte] = decode(input)
|
||||||
|
|
|
@ -95,6 +95,7 @@ class ChainParamsTest extends FlatSpec with MustMatchers {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "have the correct base58 prefix for MainNet" in {
|
it must "have the correct base58 prefix for MainNet" in {
|
||||||
|
import Base58Type._
|
||||||
//correct answers taken from https://en.bitcoin.it/wiki/List_of_address_prefixes
|
//correct answers taken from https://en.bitcoin.it/wiki/List_of_address_prefixes
|
||||||
BitcoinSUtil.encodeHex(MainNetChainParams.base58Prefixes(PubKeyAddress)) must be ("00")
|
BitcoinSUtil.encodeHex(MainNetChainParams.base58Prefixes(PubKeyAddress)) must be ("00")
|
||||||
BitcoinSUtil.encodeHex(MainNetChainParams.base58Prefixes(ScriptAddress)) must be ("05")
|
BitcoinSUtil.encodeHex(MainNetChainParams.base58Prefixes(ScriptAddress)) must be ("05")
|
||||||
|
@ -104,6 +105,7 @@ class ChainParamsTest extends FlatSpec with MustMatchers {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "have the correct base58 prefix for TestNet" in {
|
it must "have the correct base58 prefix for TestNet" in {
|
||||||
|
import Base58Type._
|
||||||
BitcoinSUtil.encodeHex(TestNetChainParams.base58Prefixes(PubKeyAddress)) must be ("6f")
|
BitcoinSUtil.encodeHex(TestNetChainParams.base58Prefixes(PubKeyAddress)) must be ("6f")
|
||||||
BitcoinSUtil.encodeHex(TestNetChainParams.base58Prefixes(ScriptAddress)) must be ("c4")
|
BitcoinSUtil.encodeHex(TestNetChainParams.base58Prefixes(ScriptAddress)) must be ("c4")
|
||||||
BitcoinSUtil.encodeHex(TestNetChainParams.base58Prefixes(SecretKey)) must be ("ef")
|
BitcoinSUtil.encodeHex(TestNetChainParams.base58Prefixes(SecretKey)) must be ("ef")
|
||||||
|
@ -112,6 +114,7 @@ class ChainParamsTest extends FlatSpec with MustMatchers {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "have the correct base58 prefix for RegTest" in {
|
it must "have the correct base58 prefix for RegTest" in {
|
||||||
|
import Base58Type._
|
||||||
BitcoinSUtil.encodeHex(RegTestNetChainParams.base58Prefixes(PubKeyAddress)) must be ("6f")
|
BitcoinSUtil.encodeHex(RegTestNetChainParams.base58Prefixes(PubKeyAddress)) must be ("6f")
|
||||||
BitcoinSUtil.encodeHex(RegTestNetChainParams.base58Prefixes(ScriptAddress)) must be ("c4")
|
BitcoinSUtil.encodeHex(RegTestNetChainParams.base58Prefixes(ScriptAddress)) must be ("c4")
|
||||||
BitcoinSUtil.encodeHex(RegTestNetChainParams.base58Prefixes(SecretKey)) must be ("ef")
|
BitcoinSUtil.encodeHex(RegTestNetChainParams.base58Prefixes(SecretKey)) must be ("ef")
|
||||||
|
|
Loading…
Add table
Reference in a new issue