mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-01 07:42:17 +00:00
Merge pull request #1 from QuickMythril/ravencoin
Added Ravencoin mainnet params
This commit is contained in:
commit
6fec8631ea
@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adapted for Ravencoin in April 2022 by Qortal dev team
|
||||||
|
* Thanks to https://github.com/coinext/ravencoinj for the references
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libdohj.params;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.*;
|
||||||
|
import org.bitcoinj.store.BlockStore;
|
||||||
|
import org.bitcoinj.store.BlockStoreException;
|
||||||
|
import org.bitcoinj.utils.MonetaryFormat;
|
||||||
|
import org.libdohj.core.AltcoinNetworkParameters;
|
||||||
|
import org.libdohj.core.AltcoinSerializer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.bitcoinj.core.Coin.COIN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common parameters for Ravencoin networks.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractRavencoinParams extends NetworkParameters implements AltcoinNetworkParameters {
|
||||||
|
/** Standard format for the RVN denomination. */
|
||||||
|
public static final MonetaryFormat RVN;
|
||||||
|
/** Standard format for the mRVN denomination. */
|
||||||
|
public static final MonetaryFormat MRVN;
|
||||||
|
/** Standard format for the "Ravenoshi" denomination. */
|
||||||
|
public static final MonetaryFormat RAVENOSHI;
|
||||||
|
|
||||||
|
public static final int RAVEN_TARGET_TIMESPAN = (int)(2016 * 60); // 1.4 days
|
||||||
|
public static final int RAVEN_TARGET_SPACING = (int)(1 * 60); // 60 seconds
|
||||||
|
public static final int RAVEN_INTERVAL = TARGET_TIMESPAN / TARGET_SPACING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of coins to be generated
|
||||||
|
*/
|
||||||
|
public static final long MAX_COINS = 21000000; // 21000000000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum money to be generated
|
||||||
|
*/
|
||||||
|
public static final Coin MAX_RAVENCOIN_MONEY = COIN.multiply(MAX_COINS);
|
||||||
|
|
||||||
|
/** Currency code for base 1 Ravencoin. */
|
||||||
|
public static final String CODE_RVN = "RVN";
|
||||||
|
/** Currency code for base 1/1,000 Ravencoin. */
|
||||||
|
public static final String CODE_MRVN = "mRVN";
|
||||||
|
/** Currency code for base 1/100,000,000 Ravencoin. */
|
||||||
|
public static final String CODE_RAVENOSHI = "Ravenoshi";
|
||||||
|
|
||||||
|
static {
|
||||||
|
RVN = MonetaryFormat.BTC.noCode()
|
||||||
|
.code(0, CODE_RVN)
|
||||||
|
.code(3, CODE_MRVN)
|
||||||
|
.code(7, CODE_RAVENOSHI);
|
||||||
|
MRVN = RVN.shift(3).minDecimals(2).optionalDecimals(2);
|
||||||
|
RAVENOSHI = RVN.shift(7).minDecimals(0).optionalDecimals(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The string returned by getId() for the main, production network where people trade things. */
|
||||||
|
public static final String ID_RVN_MAINNET = "main";
|
||||||
|
/** The string returned by getId() for the testnet. */
|
||||||
|
public static final String ID_RVN_TESTNET = "test";
|
||||||
|
/** The string returned by getId() for regtest. */
|
||||||
|
public static final String ID_RVN_REGTEST = "regtest";
|
||||||
|
|
||||||
|
public static final int RAVENCOIN_PROTOCOL_VERSION_MINIMUM = 70000;
|
||||||
|
public static final int RAVENCOIN_PROTOCOL_VERSION_CURRENT = 70001;
|
||||||
|
|
||||||
|
private static final Coin BASE_SUBSIDY = Coin.valueOf(5000, 0);
|
||||||
|
|
||||||
|
protected Logger log = LoggerFactory.getLogger(AbstractRavencoinParams.class);
|
||||||
|
|
||||||
|
public AbstractRavencoinParams() {
|
||||||
|
super();
|
||||||
|
interval = RAVEN_INTERVAL;
|
||||||
|
targetTimespan = RAVEN_TARGET_TIMESPAN;
|
||||||
|
maxTarget = Utils.decodeCompactBits(0x1e00ffffL);
|
||||||
|
|
||||||
|
packetMagic = 0x5241564e;
|
||||||
|
bip32HeaderP2PKHpub = 0x0488B21E; //The 4 byte header that serializes in base58 to "xpub"
|
||||||
|
bip32HeaderP2PKHpriv = 0x0488ADE4; //The 4 byte header that serializes in base58 to "xprv"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coin getBlockSubsidy(final int height) {
|
||||||
|
return BASE_SUBSIDY.shiftRight(height / getSubsidyDecreaseBlockCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hash to use for a block.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Sha256Hash getBlockDifficultyHash(Block block) {
|
||||||
|
return ((AltcoinBlock) block).getScryptHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonetaryFormat getMonetaryFormat() {
|
||||||
|
return RVN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coin getMaxMoney() {
|
||||||
|
return MAX_RAVENCOIN_MONEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coin getMinNonDustOutput() {
|
||||||
|
return Coin.valueOf(2730);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUriScheme() {
|
||||||
|
return "ravencoin";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMaxMoney() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkDifficultyTransitions(StoredBlock storedPrev, Block nextBlock, BlockStore blockStore)
|
||||||
|
throws VerificationException, BlockStoreException {
|
||||||
|
try {
|
||||||
|
final long newTargetCompact = calculateNewDifficultyTarget(storedPrev, nextBlock, blockStore);
|
||||||
|
final long receivedTargetCompact = nextBlock.getDifficultyTarget();
|
||||||
|
|
||||||
|
if (newTargetCompact != receivedTargetCompact)
|
||||||
|
throw new VerificationException("Network provided difficulty bits do not match what was calculated: " +
|
||||||
|
newTargetCompact + " vs " + receivedTargetCompact);
|
||||||
|
} catch (CheckpointEncounteredException ex) {
|
||||||
|
// Just have to take it on trust then
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the difficulty target expected for the next block. This includes all
|
||||||
|
* the weird cases for Litecoin such as testnet blocks which can be maximum
|
||||||
|
* difficulty if the block interval is high enough.
|
||||||
|
* TODO: this may need updating for Ravencoin; it is currently copied from Litecoin
|
||||||
|
*
|
||||||
|
* @throws CheckpointEncounteredException if a checkpoint is encountered while
|
||||||
|
* calculating difficulty target, and therefore no conclusive answer can
|
||||||
|
* be provided.
|
||||||
|
*/
|
||||||
|
public long calculateNewDifficultyTarget(StoredBlock storedPrev, Block nextBlock, BlockStore blockStore)
|
||||||
|
throws VerificationException, BlockStoreException, CheckpointEncounteredException {
|
||||||
|
final Block prev = storedPrev.getHeader();
|
||||||
|
final int previousHeight = storedPrev.getHeight();
|
||||||
|
final int retargetInterval = this.getInterval();
|
||||||
|
|
||||||
|
// Is this supposed to be a difficulty transition point?
|
||||||
|
if ((storedPrev.getHeight() + 1) % retargetInterval != 0) {
|
||||||
|
if (this.allowMinDifficultyBlocks()) {
|
||||||
|
// Special difficulty rule for testnet:
|
||||||
|
// If the new block's timestamp is more than 5 minutes
|
||||||
|
// then allow mining of a min-difficulty block.
|
||||||
|
if (nextBlock.getTimeSeconds() > prev.getTimeSeconds() + getTargetSpacing() * 2) {
|
||||||
|
return Utils.encodeCompactBits(maxTarget);
|
||||||
|
} else {
|
||||||
|
// Return the last non-special-min-difficulty-rules-block
|
||||||
|
StoredBlock cursor = storedPrev;
|
||||||
|
|
||||||
|
while (cursor.getHeight() % retargetInterval != 0
|
||||||
|
&& cursor.getHeader().getDifficultyTarget() == Utils.encodeCompactBits(this.getMaxTarget())) {
|
||||||
|
StoredBlock prevCursor = cursor.getPrev(blockStore);
|
||||||
|
if (prevCursor == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cursor = prevCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor.getHeader().getDifficultyTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No ... so check the difficulty didn't actually change.
|
||||||
|
return prev.getDifficultyTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to find a block far back in the chain. It's OK that this is expensive because it only occurs every
|
||||||
|
// two weeks after the initial block chain download.
|
||||||
|
StoredBlock cursor = storedPrev;
|
||||||
|
int goBack = retargetInterval - 1;
|
||||||
|
|
||||||
|
// Litecoin: This fixes an issue where a 51% attack can change difficulty at will.
|
||||||
|
// Go back the full period unless it's the first retarget after genesis.
|
||||||
|
// Code based on original by Art Forz
|
||||||
|
if (cursor.getHeight()+1 != retargetInterval)
|
||||||
|
goBack = retargetInterval;
|
||||||
|
|
||||||
|
for (int i = 0; i < goBack; i++) {
|
||||||
|
if (cursor == null) {
|
||||||
|
// This should never happen. If it does, it means we are following an incorrect or busted chain.
|
||||||
|
throw new VerificationException(
|
||||||
|
"Difficulty transition point but we did not find a way back to the genesis block.");
|
||||||
|
}
|
||||||
|
cursor = blockStore.get(cursor.getHeader().getPrevBlockHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
//We used checkpoints...
|
||||||
|
if (cursor == null) {
|
||||||
|
log.debug("Difficulty transition: Hit checkpoint!");
|
||||||
|
throw new CheckpointEncounteredException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Block blockIntervalAgo = cursor.getHeader();
|
||||||
|
return this.calculateNewDifficultyTargetInner(previousHeight, prev.getTimeSeconds(),
|
||||||
|
prev.getDifficultyTarget(), blockIntervalAgo.getTimeSeconds(),
|
||||||
|
nextBlock.getDifficultyTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the difficulty target expected for the next block after a normal
|
||||||
|
* recalculation interval. Does not handle special cases such as testnet blocks
|
||||||
|
* being setting the target to maximum for blocks after a long interval.
|
||||||
|
*
|
||||||
|
* @param previousHeight height of the block immediately before the retarget.
|
||||||
|
* @param prev the block immediately before the retarget block.
|
||||||
|
* @param nextBlock the block the retarget happens at.
|
||||||
|
* @param blockIntervalAgo The last retarget block.
|
||||||
|
* @return New difficulty target as compact bytes.
|
||||||
|
*/
|
||||||
|
protected long calculateNewDifficultyTargetInner(int previousHeight, final Block prev,
|
||||||
|
final Block nextBlock, final Block blockIntervalAgo) {
|
||||||
|
return this.calculateNewDifficultyTargetInner(previousHeight, prev.getTimeSeconds(),
|
||||||
|
prev.getDifficultyTarget(), blockIntervalAgo.getTimeSeconds(),
|
||||||
|
nextBlock.getDifficultyTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param previousHeight Height of the block immediately previous to the one we're calculating difficulty of.
|
||||||
|
* @param previousBlockTime Time of the block immediately previous to the one we're calculating difficulty of.
|
||||||
|
* @param lastDifficultyTarget Compact difficulty target of the last retarget block.
|
||||||
|
* @param lastRetargetTime Time of the last difficulty retarget.
|
||||||
|
* @param nextDifficultyTarget The expected difficulty target of the next
|
||||||
|
* block, used for determining precision of the result.
|
||||||
|
* @return New difficulty target as compact bytes.
|
||||||
|
*/
|
||||||
|
protected long calculateNewDifficultyTargetInner(int previousHeight, long previousBlockTime,
|
||||||
|
final long lastDifficultyTarget, final long lastRetargetTime,
|
||||||
|
final long nextDifficultyTarget) {
|
||||||
|
final int retargetTimespan = this.getTargetTimespan();
|
||||||
|
int actualTime = (int) (previousBlockTime - lastRetargetTime);
|
||||||
|
final int minTimespan = retargetTimespan / 4;
|
||||||
|
final int maxTimespan = retargetTimespan * 4;
|
||||||
|
|
||||||
|
actualTime = Math.min(maxTimespan, Math.max(minTimespan, actualTime));
|
||||||
|
|
||||||
|
BigInteger newTarget = Utils.decodeCompactBits(lastDifficultyTarget);
|
||||||
|
newTarget = newTarget.multiply(BigInteger.valueOf(actualTime));
|
||||||
|
newTarget = newTarget.divide(BigInteger.valueOf(retargetTimespan));
|
||||||
|
|
||||||
|
if (newTarget.compareTo(this.getMaxTarget()) > 0) {
|
||||||
|
log.info("Difficulty hit proof of work limit: {}", newTarget.toString(16));
|
||||||
|
newTarget = this.getMaxTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
int accuracyBytes = (int) (nextDifficultyTarget >>> 24) - 3;
|
||||||
|
|
||||||
|
// The calculated difficulty is to a higher precision than received, so reduce here.
|
||||||
|
BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
|
||||||
|
newTarget = newTarget.and(mask);
|
||||||
|
return Utils.encodeCompactBits(newTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AltcoinSerializer getSerializer(boolean parseRetain) {
|
||||||
|
return new AltcoinSerializer(this, parseRetain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getProtocolVersionNum(final ProtocolVersion version) {
|
||||||
|
switch (version) {
|
||||||
|
case PONG:
|
||||||
|
case BLOOM_FILTER:
|
||||||
|
return version.getBitcoinProtocolVersion();
|
||||||
|
case CURRENT:
|
||||||
|
return RAVENCOIN_PROTOCOL_VERSION_CURRENT;
|
||||||
|
case MINIMUM:
|
||||||
|
default:
|
||||||
|
return RAVENCOIN_PROTOCOL_VERSION_MINIMUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this network has special rules to enable minimum difficulty blocks
|
||||||
|
* after a long interval between two blocks (i.e. testnet).
|
||||||
|
*/
|
||||||
|
public boolean allowMinDifficultyBlocks() {
|
||||||
|
return this.isTestNet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTargetSpacing() {
|
||||||
|
return this.getTargetTimespan() / this.getInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CheckpointEncounteredException extends Exception { }
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Google Inc.
|
||||||
|
* Copyright 2014 Andreas Schildbach
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adapted for Ravencoin in April 2022 by Qortal dev team
|
||||||
|
* Thanks to https://github.com/coinext/ravencoinj for the references
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libdohj.params;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.*;
|
||||||
|
import org.bitcoinj.params.MainNetParams;
|
||||||
|
import org.bitcoinj.script.Script;
|
||||||
|
import org.bitcoinj.script.ScriptOpCodes;
|
||||||
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for the Ravencoin main production network on which people trade
|
||||||
|
* goods and services.
|
||||||
|
*/
|
||||||
|
public class RavencoinMainNetParams extends AbstractRavencoinParams {
|
||||||
|
public static final int MAINNET_MAJORITY_WINDOW = 1000;
|
||||||
|
public static final int MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED = 950;
|
||||||
|
public static final int MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = 750;
|
||||||
|
|
||||||
|
public RavencoinMainNetParams() {
|
||||||
|
super();
|
||||||
|
id = ID_RVN_MAINNET;
|
||||||
|
// Genesis hash is 0000006b444bc2f2ffe627be9d9e7e7a0730000870ef6eb6da46c8eae389df90
|
||||||
|
|
||||||
|
packetMagic = 0x5241564e;
|
||||||
|
maxTarget = Utils.decodeCompactBits(0x1e00ffffL);
|
||||||
|
port = 8767;
|
||||||
|
addressHeader = 60;
|
||||||
|
p2shHeader = 122;
|
||||||
|
// from https://github.com/RavenProject/Ravencoin/blob/master/src/chainparams.cpp
|
||||||
|
|
||||||
|
/* packetMagic = 0xf9beb4d9;
|
||||||
|
maxTarget = Utils.decodeCompactBits(0x1d00ffffL);
|
||||||
|
port = 8333;
|
||||||
|
addressHeader = 0;
|
||||||
|
p2shHeader = 5; */
|
||||||
|
// from https://github.com/coinext/ravencoinj/blob/master/core/src/main/java/org/bitcoinj/params/MainNetParams.java
|
||||||
|
|
||||||
|
// acceptableAddressCodes = new int[] { addressHeader, p2shHeader };
|
||||||
|
dumpedPrivateKeyHeader = 128;
|
||||||
|
|
||||||
|
this.genesisBlock = createGenesis(this);
|
||||||
|
spendableCoinbaseDepth = 100;
|
||||||
|
subsidyDecreaseBlockCount = 2100000;
|
||||||
|
|
||||||
|
String genesisHash = genesisBlock.getHashAsString();
|
||||||
|
checkState(genesisHash.equals("0000006b444bc2f2ffe627be9d9e7e7a0730000870ef6eb6da46c8eae389df90"));
|
||||||
|
// from https://github.com/RavenProject/Ravencoin/blob/master/src/chainparams.cpp
|
||||||
|
|
||||||
|
// checkState(genesisHash.equals("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
|
||||||
|
// from https://github.com/coinext/ravencoinj/blob/master/core/src/main/java/org/bitcoinj/params/MainNetParams.java
|
||||||
|
alertSigningKey = Hex.decode("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
|
||||||
|
|
||||||
|
majorityEnforceBlockUpgrade = MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE;
|
||||||
|
majorityRejectBlockOutdated = MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED;
|
||||||
|
majorityWindow = MAINNET_MAJORITY_WINDOW;
|
||||||
|
|
||||||
|
dnsSeeds = new String[] {
|
||||||
|
"seed-raven.bitactivate.com",
|
||||||
|
"seed-raven.ravencoin.com",
|
||||||
|
"seed-raven.ravencoin.org"
|
||||||
|
};
|
||||||
|
bip32HeaderP2PKHpub = 0x0488b21e; // The 4 byte header that serializes in base58 to "xpub".
|
||||||
|
bip32HeaderP2PKHpriv = 0x0488ade4; // The 4 byte header that serializes in base58 to "xprv"
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AltcoinBlock createGenesis(NetworkParameters params) {
|
||||||
|
Transaction t = new Transaction(params);
|
||||||
|
try {
|
||||||
|
// A script containing the difficulty bits and the following message:
|
||||||
|
//
|
||||||
|
// "The Times 03/Jan/2018 Bitcoin is name of the game for new generation of firms"
|
||||||
|
byte[] bytes = Utils.HEX.decode("04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73");
|
||||||
|
t.addInput(new TransactionInput(params, t, bytes));
|
||||||
|
ByteArrayOutputStream scriptPubKeyBytes = new ByteArrayOutputStream();
|
||||||
|
Script.writeBytes(scriptPubKeyBytes, Utils.HEX.decode("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"));
|
||||||
|
scriptPubKeyBytes.write(ScriptOpCodes.OP_CHECKSIG);
|
||||||
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(5000, 0), scriptPubKeyBytes.toByteArray()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Cannot happen.
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sha256Hash merkleRoot = Sha256Hash.wrap("28ff00a867739a352523808d301f504bc4547699398d70faf2266a8bae5f3516");
|
||||||
|
AltcoinBlock genesisBlock = new AltcoinBlock(params, Block.BLOCK_VERSION_GENESIS, Sha256Hash.ZERO_HASH,
|
||||||
|
merkleRoot, 1514999494L, 0x1e00ffffL, 25023712, Arrays.asList(t));
|
||||||
|
// from https://github.com/RavenProject/Ravencoin/blob/master/src/chainparams.cpp
|
||||||
|
|
||||||
|
// merkleRoot, 1231006505L, 0x1d00ffffL, 2083236893, Arrays.asList(t));
|
||||||
|
// from https://github.com/coinext/ravencoinj/blob/master/core/src/main/java/org/bitcoinj/params/MainNetParams.java
|
||||||
|
|
||||||
|
return genesisBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RavencoinMainNetParams instance;
|
||||||
|
public static synchronized RavencoinMainNetParams get() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new RavencoinMainNetParams();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPaymentProtocolId() {
|
||||||
|
return ID_RVN_MAINNET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTestNet() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user