Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More coins #353

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions coinConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,52 @@
"mixIn": 4,
"shortCode": "KRB"
},
"etn": {
"funcFile": "./lib/coins/etn.js",
"paymentFile": "./payment_systems/etn.js",
"sigDigits": 100,
"name": "Electroneum",
"mixIn": 0,
"shortCode": "ETN"
},
"stl": {
"funcFile": "./lib/coins/stl.js",
"paymentFile": "./payment_systems/stl.js",
"sigDigits": 10000,
"name": "Stellitecoin",
"mixIn": 0,
"shortCode": "STL"
},
"sumo": {
"funcFile": "./lib/coins/sumo.js",
"paymentFile": "./payment_systems/sumo.js",
"sigDigits": 10,
"name": "Sumocoin",
"mixIn": 0,
"shortCode": "SUMO"
},
"aeon": {
"funcFile": "./lib/coins/aeon.js",
"paymentFile": "./payment_systems/aeon.js",
"sigDigits": 1000000000000,
"name": "Aeon Coin",
"mixIn": 4,
"shortCode": "AEON"
},
"omb": {
"funcFile": "./lib/coins/omb.js",
"paymentFile": "./payment_systems/omb.js",
"sigDigits": 1000000000000,
"name": "Ombre",
"mixIn": 12,
"shortCode": "OMB"
},
"msr": {
"funcFile": "./lib/coins/msr.js",
"paymentFile": "./payment_systems/msr.js",
"sigDigits": 1000000000000,
"name": "Masari",
"mixIn": 12,
"shortCode": "MSR"
}
}
163 changes: 163 additions & 0 deletions lib/coins/etn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
"use strict";
const bignum = require('bignum');
const cnUtil = require('cryptonote-util');
const multiHashing = require('multi-hashing');
const crypto = require('crypto');
const debug = require('debug')('coinFuncs');

let hexChars = new RegExp("[0-9a-f]+");

function Coin(data){
this.bestExchange = global.config.payout.bestExchange;
this.data = data;
let instanceId = crypto.randomBytes(4);
//Edit coin and pool donate to etn-pool.org =)
this.coinDevAddress = "etnk972DGajHFYWAnPkMBb88apD6XgdoWAciLHw6w4ZVBapaxMRSxzsjMUjX6ZX7he4fseqMQP3LZV5WS5cyiyRn6ws2VT8sgh"; // Developer Address
this.poolDevAddress = "etnk972DGajHFYWAnPkMBb88apD6XgdoWAciLHw6w4ZVBapaxMRSxzsjMUjX6ZX7he4fseqMQP3LZV5WS5cyiyRn6ws2VT8sgh"; // ArqTras PoolDev Address

this.blockedAddresses = [
this.coinDevAddress,
this.poolDevAddress
];

this.exchangeAddresses = [
"etnjzKFU6ogESSKRZZbdqraPdcKVxEC17Cm1Xvbyy76PARQMmgrgceH4krAH6xmjKwJ3HtSAKuyFm1BBWYqtchtq9tBap8Qr4M", //Cryptopia
]; // These are addresses that MUST have a paymentID to perform logins with.

this.prefix = 18018;
this.intPrefix = 18019;

if (global.config.general.testnet === true){
this.prefix = 18018;
this.intPrefix = 18019;
}

this.supportsAutoExchange = false;

this.niceHashDiff = 400000;

this.getBlockHeaderByID = function(blockId, callback){
global.support.rpcDaemon('getblockheaderbyheight', {"height": blockId}, function (body) {
if (body.hasOwnProperty('result')){
return callback(null, body.result.block_header);
} else {
console.error(JSON.stringify(body));
return callback(true, body);
}
});
};

this.getBlockHeaderByHash = function(blockHash, callback){
global.support.rpcDaemon('getblockheaderbyhash', {"hash": blockHash}, function (body) {
if (typeof(body) !== 'undefined' && body.hasOwnProperty('result')){
return callback(null, body.result.block_header);
} else {
console.error(JSON.stringify(body));
return callback(true, body);
}
});
};

this.getLastBlockHeader = function(callback){
global.support.rpcDaemon('getlastblockheader', [], function (body) {
if (typeof(body) !== 'undefined' && body.hasOwnProperty('result')){
return callback(null, body.result.block_header);
} else {
console.error(JSON.stringify(body));
return callback(true, body);
}
});
};

this.getBlockTemplate = function(walletAddress, callback){
global.support.rpcDaemon('getblocktemplate', {
reserve_size: 17,
wallet_address: walletAddress
}, function(body){
return callback(body);
});
};

this.baseDiff = function(){
return bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16);
};

this.validateAddress = function(address){
// This function should be able to be called from the async library, as we need to BLOCK ever so slightly to verify the address.
address = new Buffer(address);
if (cnUtil.address_decode(address) === this.prefix){
return true;
}
return cnUtil.address_decode_integrated(address) === this.intPrefix;
};

this.convertBlob = function(blobBuffer){
return cnUtil.convert_blob(blobBuffer);
};

this.constructNewBlob = function(blockTemplate, NonceBuffer){
return cnUtil.construct_block_blob(blockTemplate, NonceBuffer);
};

this.getBlockID = function(blockBuffer){
return cnUtil.get_block_id(blockBuffer);
};

this.BlockTemplate = function(template) {
/*
Generating a block template is a simple thing. Ask for a boatload of information, and go from there.
Important things to consider.
The reserved space is 13 bytes long now in the following format:
Assuming that the extraNonce starts at byte 130:
|130-133|134-137|138-141|142-145|
|minerNonce/extraNonce - 4 bytes|instanceId - 4 bytes|clientPoolNonce - 4 bytes|clientNonce - 4 bytes|
This is designed to allow a single block template to be used on up to 4 billion poolSlaves (clientPoolNonce)
Each with 4 billion clients. (clientNonce)
While being unique to this particular pool thread (instanceId)
With up to 4 billion clients (minerNonce/extraNonce)
Overkill? Sure. But that's what we do here. Overkill.
*/

// Set this.blob equal to the BT blob that we get from upstream.
this.blob = template.blocktemplate_blob;
this.idHash = crypto.createHash('md5').update(template.blocktemplate_blob).digest('hex');
// Set this.diff equal to the known diff for this block.
this.difficulty = template.difficulty;
// Set this.height equal to the known height for this block.
this.height = template.height;
// Set this.reserveOffset to the byte location of the reserved offset.
this.reserveOffset = template.reserved_offset;
// Set this.buffer to the binary decoded version of the BT blob.
this.buffer = new Buffer(this.blob, 'hex');
// Copy the Instance ID to the reserve offset + 4 bytes deeper. Copy in 4 bytes.
instanceId.copy(this.buffer, this.reserveOffset + 4, 0, 3);
// Generate a clean, shiny new buffer.
this.previous_hash = new Buffer(32);
// Copy in bytes 7 through 39 to this.previous_hash from the current BT.
this.buffer.copy(this.previous_hash, 0, 7, 39);
// Reset the Nonce. - This is the per-miner/pool nonce
this.extraNonce = 0;
// The clientNonceLocation is the location at which the client pools should set the nonces for each of their clients.
this.clientNonceLocation = this.reserveOffset + 12;
// The clientPoolLocation is for multi-thread/multi-server pools to handle the nonce for each of their tiers.
this.clientPoolLocation = this.reserveOffset + 8;
this.nextBlob = function () {
// Write a 32 bit integer, big-endian style to the 0 byte of the reserve offset.
this.buffer.writeUInt32BE(++this.extraNonce, this.reserveOffset);
// Convert the blob into something hashable.
return global.coinFuncs.convertBlob(this.buffer).toString('hex');
};
// Make it so you can get the raw block blob out.
this.nextBlobWithChildNonce = function () {
// Write a 32 bit integer, big-endian style to the 0 byte of the reserve offset.
this.buffer.writeUInt32BE(++this.extraNonce, this.reserveOffset);
// Don't convert the blob to something hashable. You bad.
return this.buffer.toString('hex');
};
};

this.cryptoNight = multiHashing.cryptonight;

}

module.exports = Coin;
161 changes: 161 additions & 0 deletions lib/coins/grf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
"use strict";
const bignum = require('bignum');
const cnUtil = require('cryptonote-util');
const multiHashing = require('multi-hashing');
const crypto = require('crypto');
const debug = require('debug')('coinFuncs');

let hexChars = new RegExp("[0-9a-f]+");

function Coin(data){
this.bestExchange = global.config.payout.bestExchange;
this.data = data;
let instanceId = crypto.randomBytes(4);
this.coinDevAddress = "GAQsx9YDqkN5WMiGgZ8AqS9S5Wg7HwNFLdPDqjmvwxs8ekKy6L6ph69TFU5uxF1MzySWBwxKPKtDxPLJ7fD6j1Xu3MWhYyS"; // ArqTras
this.poolDevAddress = "GAQsx9YDqkN5WMiGgZ8AqS9S5Wg7HwNFLdPDqjmvwxs8ekKy6L6ph69TFU5uxF1MzySWBwxKPKtDxPLJ7fD6j1Xu3MWhYyS"; // ArqTras

this.blockedAddresses = [
this.coinDevAddress,
this.poolDevAddress,
];

this.exchangeAddresses = [
]; // These are addresses that MUST have a paymentID to perform logins with.

this.prefix = 90;
this.intPrefix = 91;

if (global.config.general.testnet === true){
this.prefix = 84;
this.intPrefix = 85;
}

this.supportsAutoExchange = false;

this.niceHashDiff = 405000;

this.getBlockHeaderByID = function(blockId, callback){
global.support.rpcDaemon('getblockheaderbyheight', {"height": blockId}, function (body) {
if (body.hasOwnProperty('result')){
return callback(null, body.result.block_header);
} else {
console.error(JSON.stringify(body));
return callback(true, body);
}
});
};

this.getBlockHeaderByHash = function(blockHash, callback){
global.support.rpcDaemon('getblockheaderbyhash', {"hash": blockHash}, function (body) {
if (typeof(body) !== 'undefined' && body.hasOwnProperty('result')){
return callback(null, body.result.block_header);
} else {
console.error(JSON.stringify(body));
return callback(true, body);
}
});
};

this.getLastBlockHeader = function(callback){
global.support.rpcDaemon('getlastblockheader', [], function (body) {
if (typeof(body) !== 'undefined' && body.hasOwnProperty('result')){
return callback(null, body.result.block_header);
} else {
console.error(JSON.stringify(body));
return callback(true, body);
}
});
};

this.getBlockTemplate = function(walletAddress, callback){
global.support.rpcDaemon('getblocktemplate', {
reserve_size: 17,
wallet_address: walletAddress
}, function(body){
return callback(body);
});
};

this.baseDiff = function(){
return bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16);
};

this.validateAddress = function(address){
// This function should be able to be called from the async library, as we need to BLOCK ever so slightly to verify the address.
address = new Buffer(address);
if (cnUtil.address_decode(address) === this.prefix){
return true;
}
return cnUtil.address_decode_integrated(address) === this.intPrefix;
};

this.convertBlob = function(blobBuffer){
return cnUtil.convert_blob(blobBuffer);
};

this.constructNewBlob = function(blockTemplate, NonceBuffer){
return cnUtil.construct_block_blob(blockTemplate, NonceBuffer);
};

this.getBlockID = function(blockBuffer){
return cnUtil.get_block_id(blockBuffer);
};

this.BlockTemplate = function(template) {
/*
Generating a block template is a simple thing. Ask for a boatload of information, and go from there.
Important things to consider.
The reserved space is 13 bytes long now in the following format:
Assuming that the extraNonce starts at byte 130:
|130-133|134-137|138-141|142-145|
|minerNonce/extraNonce - 4 bytes|instanceId - 4 bytes|clientPoolNonce - 4 bytes|clientNonce - 4 bytes|
This is designed to allow a single block template to be used on up to 4 billion poolSlaves (clientPoolNonce)
Each with 4 billion clients. (clientNonce)
While being unique to this particular pool thread (instanceId)
With up to 4 billion clients (minerNonce/extraNonce)
Overkill? Sure. But that's what we do here. Overkill.
*/

// Set this.blob equal to the BT blob that we get from upstream.
this.blob = template.blocktemplate_blob;
this.idHash = crypto.createHash('md5').update(template.blocktemplate_blob).digest('hex');
// Set this.diff equal to the known diff for this block.
this.difficulty = template.difficulty;
// Set this.height equal to the known height for this block.
this.height = template.height;
// Set this.reserveOffset to the byte location of the reserved offset.
this.reserveOffset = template.reserved_offset;
// Set this.buffer to the binary decoded version of the BT blob.
this.buffer = new Buffer(this.blob, 'hex');
// Copy the Instance ID to the reserve offset + 4 bytes deeper. Copy in 4 bytes.
instanceId.copy(this.buffer, this.reserveOffset + 4, 0, 3);
// Generate a clean, shiny new buffer.
this.previous_hash = new Buffer(32);
// Copy in bytes 7 through 39 to this.previous_hash from the current BT.
this.buffer.copy(this.previous_hash, 0, 7, 39);
// Reset the Nonce. - This is the per-miner/pool nonce
this.extraNonce = 0;
// The clientNonceLocation is the location at which the client pools should set the nonces for each of their clients.
this.clientNonceLocation = this.reserveOffset + 12;
// The clientPoolLocation is for multi-thread/multi-server pools to handle the nonce for each of their tiers.
this.clientPoolLocation = this.reserveOffset + 8;
this.nextBlob = function () {
// Write a 32 bit integer, big-endian style to the 0 byte of the reserve offset.
this.buffer.writeUInt32BE(++this.extraNonce, this.reserveOffset);
// Convert the blob into something hashable.
return global.coinFuncs.convertBlob(this.buffer).toString('hex');
};
// Make it so you can get the raw block blob out.
this.nextBlobWithChildNonce = function () {
// Write a 32 bit integer, big-endian style to the 0 byte of the reserve offset.
this.buffer.writeUInt32BE(++this.extraNonce, this.reserveOffset);
// Don't convert the blob to something hashable. You bad.
return this.buffer.toString('hex');
};
};

this.cryptoNight = multiHashing.cryptonight;

}

module.exports = Coin;
Loading