You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have studied the code you use to create a signature :
https://github.com/etherdelta/bots/blob/master/js/service.js
const sign = (msgToSignIn, privateKeyIn) => {
const prefixMessage = (msgIn) => {
let msg = msgIn;
msg = new Buffer(msg.slice(2), 'hex');
msg = Buffer.concat([
new Buffer(`\x19Ethereum Signed Message:\n${msg.length.toString()}`),
msg]);
msg = self.web3.sha3(`0x${msg.toString('hex')}`, { encoding: 'hex' });
msg = new Buffer(msg.slice(2), 'hex');
return `0x${msg.toString('hex')}`;
};
const privateKey = privateKeyIn.substring(0, 2) === '0x' ?
privateKeyIn.substring(2, privateKeyIn.length) : privateKeyIn;
const msgToSign = prefixMessage(msgToSignIn);
try {
const sig = ethUtil.ecsign(
new Buffer(msgToSign.slice(2), 'hex'),
new Buffer(privateKey, 'hex'));
const r = `0x${sig.r.toString('hex')}`;
const s = `0x${sig.s.toString('hex')}`;
const v = sig.v;
const result = { r, s, v, msg: msgToSign };
return result;
} catch (err) {
throw new Error(err);
}
};
With that I have modified the function CreateOrder in the c# Bot, because the signature mechanism didn't work :
internal Order CreateOrder(OrderType orderType, BigInteger expires, BigInteger price, BigInteger amount)
{
if (Config.PrivateKey.Length != 64)
throw new Exception("WARNING: user_wallet_private_key must be a hexadecimal string of 64 characters long");
var uc = new UnitConversion();
var amountBigNum = amount;
var amountBaseBigNum = (amount * price) / uc.ToWei(1);
var tokenGet = orderType == OrderType.Buy ? Config.Token : ZeroToken;
var tokenGive = orderType == OrderType.Sell ? Config.Token : ZeroToken;
var amountGet = orderType == OrderType.Buy ? amountBigNum : amountBaseBigNum;
var amountGive = orderType == OrderType.Sell ? amountBigNum : amountBaseBigNum;
var orderNonce = new Random().Next();
var contractAddr = Web3.ToChecksumAddress(Config.AddressEtherDelta);
tokenGet = Web3.ToChecksumAddress(tokenGet);
tokenGive = Web3.ToChecksumAddress(tokenGive);
var user = Web3.ToChecksumAddress(Config.User);
/*
* First Step : Hash the order
*/
var plainData = new object[]
{
contractAddr,
tokenGet,
amountGet,
tokenGive,
amountGive,
expires,
orderNonce
};
var prms = new[] {
new Parameter("address",1),
new Parameter("address",1),
new Parameter("uint256",1),
new Parameter("address",1),
new Parameter("uint256",1),
new Parameter("uint256",1),
new Parameter("uint256",1)
};
var pe = new ParametersEncoder();
var data = pe.EncodeParameters(prms, plainData);
var ms = new MessageSigner();
var messageHashBytes = ms.Hash(data);
/*
* Second step : create the ethSignaturePrefixx
*/
var ethSignaturePrefixByteArray = Encoding.ASCII.GetBytes($"\u0019Ethereum Signed Message:\n{messageHashBytes.Length}");
/*
* Third Step : add the ethPrefix to the hashBytes and hash again
*/
int length = ethSignaturePrefixByteArray.Length + messageHashBytes.Length;
byte[] sum = new byte[length];
ethSignaturePrefixByteArray.CopyTo(sum, 0);
messageHashBytes.CopyTo(sum, ethSignaturePrefixByteArray.Length);
var signatureBase = ms.Hash(sum);
/*
* Fourth Step : Sign the message
* I have created a custom function CreateStringSignature2
* CreateStringSignature2 is the same function that CreateStringSignature in Nethereum
* the only difference is that CreateStringSignature2 is public
*/
var key = new EthECKey(Config.PrivateKey.HexToByteArray(), true);
var signature = CreateStringSignature2(key.SignAndCalculateV(signatureBase));
var ethEcdsa = MessageSigner.ExtractEcdsaSignature(signature);
/*
* Fifth Step : Create the order
*/
var order = new Order
{
AmountGet = new HexBigInteger(amountGet),
AmountGive = new HexBigInteger(amountGive),
TokenGet = tokenGet,
TokenGive = tokenGive,
ContractAddr = contractAddr,
Expires = expires,
Nonce = orderNonce,
User = user,
V = ethEcdsa.V,
R = ethEcdsa.R.ToHex(true),
S = ethEcdsa.S.ToHex(true)
};
/*
* Checking Signature
*/
/*
* First Step : Create a Fake WebSocket Message
*/
var message = new Message
{
Event = "message",
Data = new
{
amountGive = order.AmountGive.Value,
tokenGive = order.TokenGive,
amountGet = order.AmountGet.Value,
tokenGet = order.TokenGet,
contractAddr = Config.AddressEtherDelta,
expires = order.Expires,
nonce = order.Nonce,
user = order.User,
v = order.V,
r = order.R,
s = order.S,
}
}.ToString();
/*
* Second Step : Hash the message
*/
Message messageParsed = Message.ParseMessage(message);
var orderChecking = (JObject)messageParsed.Data;
plainData = new object[]
{
Web3.ToChecksumAddress(orderChecking["contractAddr"].ToString()),
Web3.ToChecksumAddress(orderChecking["tokenGet"].ToString()),
new BigInteger((decimal)orderChecking["amountGet"]),
Web3.ToChecksumAddress(orderChecking["tokenGive"].ToString()),
new BigInteger((decimal)orderChecking["amountGive"]),
new BigInteger((decimal)orderChecking["expires"]),
new BigInteger((decimal)orderChecking["nonce"]),
};
prms = new[] {
new Parameter("address",1),
new Parameter("address",1),
new Parameter("uint256",1),
new Parameter("address",1),
new Parameter("uint256",1),
new Parameter("uint256",1),
new Parameter("uint256",1)
};
pe = new ParametersEncoder();
data = pe.EncodeParameters(prms, plainData);
messageHashBytes = ms.Hash(data);
/*
* Third step : create the ethSignaturePrefix
*/
ethSignaturePrefixByteArray = Encoding.ASCII.GetBytes($"\u0019Ethereum Signed Message:\n{messageHashBytes.Length}");
/*
* Fourth Step : add the ethPrefix to the hashBytes and hash again
*/
length = ethSignaturePrefixByteArray.Length + messageHashBytes.Length;
sum = new byte[length];
ethSignaturePrefixByteArray.CopyTo(sum, 0);
messageHashBytes.CopyTo(sum, ethSignaturePrefixByteArray.Length);
signatureBase = ms.Hash(sum);
/*
* Retreive the public key and compare
*/
string publicKey = ms.EcRecover(signatureBase, signature);
if (publicKey.ToLower() != Config.User.ToLower())
throw new Exception("WARNING: incorect signature");
return order;
}
At the end of the function I check if the publickey that I have retreived from the signature matchs my public key and it works. But as soon as I send the message via the websocket I have a error :
Did not place order because available volume too low.
This error means for me that my signature is not correct.
If I remove the prefix I have still a error
I don't understand why. Can you help me ?
Thanks
Jehan
The text was updated successfully, but these errors were encountered:
Hi,
I have studied the code you use to create a signature :
With that I have modified the function CreateOrder in the c# Bot, because the signature mechanism didn't work :
At the end of the function I check if the publickey that I have retreived from the signature matchs my public key and it works. But as soon as I send the message via the websocket I have a error :
This error means for me that my signature is not correct.
If I remove the prefix I have still a error
I don't understand why. Can you help me ?
Thanks
Jehan
The text was updated successfully, but these errors were encountered: