Filip,
I got everything to work the way I intended except for the transfer of gains from the contract to the customer’s account. It works perfectly fine during migrations, but when I call the same contract function “sendMoney” from the main.js file, the transmission and reception of the function parameters works as before, but there is never any transfer of funds. So the same contract function supplied with the same input parameters and producing the same output values works when it is called during migration and doesn’t work when it is activated via main.js. As you can imagine, I have tried everything that I could think of to fix this problem, and I absolutely did verify that the input is received properly, but the fact remains that the function works or doesn’t work depending on the calling context. Another, problem was that the transmission of large wei-integer values also works only during migration.The BigNumber function is properly recognized in main.js, but its functionality in transmitting data to the contract is somehow not the same. I more or less solved this problem by breaking up the ether-to-wei conversion into two separate steps (one in main,js and one in solidity), but this “solution” is a bit crummy and not fully satisfactory.
To make this more precise, here is the command that I used in main.js to activate the sendMoney function in the contract:
gain = Math.round(2000000*gain);
contractInstance.methods.sendMoney(customerAddress,gain).call({from:owner})then(function(transferAmount){console.log(transferAmount);});
All the parameters are correctly received and the transferAmount output is correct, but there is, as I said no transfer of funds. By contrast, there is a transfer of funds when I use the following call during migration:
await instance.sendMoney(accounts[3], 1000000, {from: accounts[0]});
Finally, the sendMoney function in solidity looks as follows:
function sendMoney(address payable customerAddress, uint transferAmount) public onlyOwner returns(uint){
transferAmount = transferAmount*1000000000000;
balance -= transferAmount;
customerAddress.transfer(transferAmount);
return(transferAmount);}
The only other fairly major problem that I ran into was the fact that the now%2 function that you advertised in your video, always produced the same value. It produced different values for different migrations, but for a given contractinstance (or instance) it always produced the same output. To get around that problem, I cooked up a different pseudo-random function using hashes. Here is what it looks like:
function random(bytes memory n) public view onlyOwner returns(uint){
return uint256(keccak256(n)) % 10;}
It produces a pseudo-random digit between zero and nine that determines where my number animation comes to a halt. The pseudo-random encryption and the corresponding call in main.js look as follows:
var encoding = "RETEEssdf34fgdcccvv565(some random string)";
var date = new Date();
contractInstance.methods.random(web3.utils.fromAscii(date + encoding)).call({from: owner} then(function(randomValue){
totalCount = 18 + 1*randomValue;
So the idea is to produce a new date string every one second and then to generate the hash of the concatenation of that date string with the random string shown above. Taking the modulo to the base ten of this hash, you end up with a pseudo-random digit between 0 and 9. So far as I can tell, this simple encryption method is nearly unbreakable because the encoding string can be arbitrarily long and complicated.
I took a screen video of my machine in action, but your end of the system didn’t allow me to attach it. So here is a screen capture instead:
For the main.js program (shown below), I used a nested sequence of promise calls, and I was wondering whether you had any comments to make about that choice.
var web3 = new Web3(Web3.givenProvider);
var contractInstance;
var lastN = 0;
var potentialGainLoss = 0;
var encoding = "RETEEssdf34fgdcccvv565(some random string)";
var owner = "0x30c2beE07179b5ef41fcd1017eDc734b2983E26B";
$(document).ready(function(){
window.ethereum.enable().then(function(accounts){
contractInstance = new web3.eth.Contract(abi, "0x872be5C771228602b787515e04D3AF1ADDBD1C2e", {from: accounts[0]});
console.log(contractInstance);
ctx.font = "45px Arial";
$("#submit_and_play_button").click(submitAndPlay);
function submitAndPlay(){
var onZero = 0;
var onOne = 0;
var totalCount = 0;
var customerAddress = $("#account_input").val();
function setColor(m){
if(m % 2 == 0){
ctx.fillStyle = "black";
}else{
ctx.fillStyle = "white";
}
}
if(customerAddress.length == 42){
setColor(lastN);
ctx.fillText(lastN % 2,62+lastN*50,91);
onZero = $("#on_zero_input").val();
onOne = $("#on_one_input").val();
potentialGainLoss = web3.utils.toWei(Math.abs(onZero - onOne).toString(), "ether");
contractInstance.methods.getBalance().call().then(function(contractBalance){
if(1*contractBalance > 1*potentialGainLoss){
var config = {from: customerAddress, value: potentialGainLoss};
contractInstance.methods.receiveMoney().send(config).then(function(){
var date = new Date();
var count = 0;
var n = 0;
contractInstance.methods.random(web3.utils.fromAscii(date + encoding)).call({from: owner})
.then(function(randomValue){
totalCount = 18 + 1*randomValue;
ctx.fillStyle = "red";
ctx.fillText(0,62,91);
var id = setInterval(runNumbers,200);
function runNumbers() {
if(Math.floor(count/9) % 2 == 0){
n++;
}else{
n--;
}
if(count == totalCount){
clearInterval(id);
}else{
setColor(n-1);
if(Math.floor(count/9) % 2 == 0){
ctx.fillText((n-1) % 2,62+(n-1)*50,91);
}else{
ctx.fillText((n+1) % 2,62+(n+1)*50,91);
}
ctx.fillStyle = "red";
ctx.fillText(n % 2,62+n*50,91);
lastN = n;
count++;
}
}
}).then(function(){
var gain = (onOne - onZero)*(2*(totalCount % 2) - 1);
if(gain<0){
$("#gain_output").text("0 ether");
$("#loss_output").text(Math.abs(gain) + " ether");
}else{
$("#loss_output").text("0 ether");
$("#gain_output").text(gain + " ether");
gain = Math.round(2000000*gain);
contractInstance.methods.sendMoney(customerAddress, gain).call({from: owner}).then(function(transferAmount){
console.log(transferAmount);
});
}
});
});
}else{
alert("Your bet is too large!");
}
});
}else{
alert("Invalid Address!");
}
}
});
});