consensys solidity supply chain exercise - javascript

i'm currently passing 22 of 23 #openzeppelin/test-helpers when i run $ truffle test on my clone of the consensys supply-chain-exercise
why am i getting the following error and does it relate to the code below?
Wrong kind of exception received
+ expected - actual
-VM Exception while processing transaction: revert Not enough payment sent -- Reason given: Not enough payment sent.
+invalid opcode
SupplyChain.sol
modifier paidEnough(uint _price) {
require(msg.value >= _price, "Not enough payment sent"); // require(msg.value >= _price);
_;
}
function buyItem(uint sku) public payable forSale(sku) paidEnough(items[sku].price) checkValue(sku) { // 1. it should be payable in order to receive refunds
items[sku].seller.transfer(items[sku].price); // 2. this should transfer money to the seller
items[sku].buyer = msg.sender; // 3. set the buyer as the person who called this transaction
items[sku].state = State.Sold; // 4. set the state to Sold
// 5. this function should use 3 modifiers to check: if the item is for sale, if the buyer paid enough, and the value after the function is called to make sure the buyer is refunded any excess ether sent
emit LogSold(sku); // 6. call the event associated with this function
}
supply_chain.test.js
it("should error when not enough value is sent when purchasing an item", async () => {
await instance.addItem(name, price, { from: alice });
await expectRevert.assertion(instance.buyItem(0, { from: bob, value: 1 }));
});
thanks!

Related

"Message: invalid data; odd-length - 0x0" error, solidity or javascript error

We wrote a Smart Contract in Solidity language. It has a function taking a string as one of it's arguments. We also wrote unit tests for the functions. The unit test for a function I mentioned just yet gives an error as follows:
Message: invalid data; odd-length - 0x0.
How can we fix the issue?
We are certain it gives error due to this argument being string because the call doesn't enter the solidity function at all; we did console.log() and it didn't log . We are developing in Remix compiler.
//the call I make from js test code, user_account2 being an address:
await mygov.connect(user_account2).submitSurvey("abc", 21e6 , 3 , 2);
//the function from the solidity smart contract:
function submitSurvey(string memory ipfshash,uint surveydeadline,uint numchoices, uint atmostchoice) public returns (uint surveyid) {
User storage owner = users[msg.sender];
require(isMember(owner), "1");
require(owner.myGovTokens >=2, "2");
require(owner.myGovTokens >2 || owner.myGovTokensLockedUntil <= block.timestamp, "3");
uint[] memory results = new uint[](numchoices) ;
Survey memory mysurvey = Survey({
Ipfshash : ipfshash,
Owner: msg.sender,
Deadline: surveydeadline,
SurveyId: surveyid,
AtmostChoice: atmostchoice,
NumChoices: numchoices,
NumTaken : 0,
Results : results
});
transferToken(address(this), 2);
address payable to_sc = payable(address(this));
transfer(to_sc, surveyCreationFee);
donatedWei += surveyCreationFee;
surveys.push(mysurvey);
surveyid = surveys.length - 1 ;
mysurvey.SurveyId = surveyid;
return (surveyid);
}

Passing a Smart Contract Function Parameter Derived from a Struct to Its Interaction Script

I'm trying to interact with a contract I just deployed with a JavaScript file on HardHat. However, I'm getting an error; I know why it's being caused, but I don't know how to fix it. In my contract I have a struct defined as FlashParams, and I have a function that uses it as a parameter as seen here (it's only part of my code since I know the rest of it isn't causing any issues):
//fee1 is the fee of the pool from the initial borrow
//fee2 is the fee of the first pool to arb from
//fee3 is the fee of the second pool to arb from
struct FlashParams {
address token0;
address token1;
uint24 fee1;
uint256 amount0;
uint256 amount1;
uint24 fee2;
uint24 fee3;
}
// fee2 and fee3 are the two other fees associated with the two other pools of token0 and token1
struct FlashCallbackData {
uint256 amount0;
uint256 amount1;
address payer;
PoolAddress.PoolKey poolKey;
uint24 poolFee2;
uint24 poolFee3;
}
/// #param params The parameters necessary for flash and the callback, passed in as FlashParams
/// #notice Calls the pools flash function with data needed in `uniswapV3FlashCallback`
function initFlash(FlashParams memory params) external onlyOwner {
PoolAddress.PoolKey memory poolKey =
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee1});
IUniswapV3Pool pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));
In my JS file I'm trying to pass the parameter from the contract as an argument in .initFlash(), but I don't know how to. Here's my JS file:
async function main() {
const address = '0x90A39BaC0D3A796b52f0394b9A97897d8F26eB1c8';
const PairFlash = await ethers.getContractFactory('PairFlash');
const pairflash = await PairFlash.attach(address);
const value = await pairflash.initFlash();
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
And here is the error:
Error: missing argument: passed to contract (count=0, expectedCount=1, code=MISSING_ARGUMENT, version=contracts/5.5.0)
reason: 'missing argument: passed to contract',
code: 'MISSING_ARGUMENT',
count: 0,
expectedCount: 1
Does anybody know how to fix this? Thank you!
I figured it out. The inputs for the JS file should be an a array format because this is the equivalent of a struct in solidity.

How to update Stripe coupon "times_redeemed" manually from api ? NodeJS

I am trying to apply a coupon while I am creating a payment Intent in stripe.
Every thing is going well but I cant manually update the number of times that coupon had been used.
I have checked the stripe doc, but found nothing. Can Someone help?
This is the stripe coupon specific doc:
Stripe Coupon Object API Doc
This is my code where I am changing the price according to the percent_off of the coupon. Everything goes well, but at the end when I am calling updateCoupon function its showing me error.
import { stripe } from "../utils/stripeInstance";
export const createPaymentIntent = async (req, res) => {
try {
const { tplan, couponCode, cust_id } = req.body;
console.log("Coupon Code==>", couponCode);
let price = 0;
//coupon redeemed
let cr = 0;
if (tplan === "smash") price = 599 * 100;
else if (tplan === "smash+") price = 999 * 100;
else return res.status(400).send("Invalid plan");
console.log("Price Before Coupon==>", price);
if (couponCode) {
const coupon = await stripe.coupons.retrieve(couponCode);
if (coupon.valid) {
price = price - (price * coupon.percent_off) / 100;
cr = coupon.times_redeemed;
}
}
console.log("Price After Coupon==>", price);
const paymentIntent = await stripe.paymentIntents.create({
amount: price,
currency: "inr",
payment_method_types: ["card"],
customer: cust_id,
});
const updateCoupon = await stripe.coupons.update(couponCode, {
times_redeemed: cr + 1,
metadata: {
used: true,
},
});
return res.status(200).send({
paymentId: paymentIntent.id,
status: paymentIntent.status,
clientSecret: paymentIntent.client_secret,
});
} catch (err) {
res.status(500).json({ statusCode: 500, message: err.message });
}
};
Error is only when I am updating the coupon by calling updateCoupon function above.This is showing in error.
Basically what I am assuming that it does not getting proper attributes, may be there is any other correct way to do it. Can anyone help me , Thank You ❤️
The only things about a coupon you can update once it is created are the metadata and the name properties, as specified here.
The times_redeemed is incremented by Stripe when a coupon is applied to a customer's purchase as part of an invoice.
However, it appears there is a larger confusion here. The reason you are having to write all these functions (fetching the coupon, modifying the amount to charge, etc.) is you are trying to apply coupons to one-off charges with Payment Intents.
Also why Stripe does not allow manual updating of times_redeemed. It's intended as an internal counter and only incremented as it processes a charge where the coupon code was applied.
Coupons do not work with conventional one-off charges.
-- Stripe API Ref
You can review how Stripe Coupons are supposed to function with Subscriptions here.
If you want to offer your customers a way to apply your own coupon discounts to the amount you charge, you will need to maintain those records in your own data models. You could use the Stripe Coupon object as a starting point and design your own database records.
But at present Stripe does not support coupons for one-off purchases

Without a delay, 'update' won't fire

I have the following code:
myTable()
.update(data, {
where: criteria
})
.then(delay(100))
.then((entries) => {
...
...
The .then(delay(100)) part sets a delay of 100ms.
If I don't use that delay, sometimes entries (the resulted updated rows) aren't correct, meaning their fields were not updated. But sometimes they are.
If I'm using the delay, the content of entries is always correct.
Why do I have to set a delay for it to work?
My local MySQL my.cnf file:
[mysqld]
general_log_file = /var/log/mysql.log
general_log = 1
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
innodb_file_per_table = 1
innodb_log_file_size = 100M
interactive_timeout = 32000
lock_wait_timeout = 41536000
net_read_timeout = 120
net_write_timeout = 900
wait_timeout = 32000
max_allowed_packet = 1G
innodb_buffer_pool_size = 1G
In terms of the table schema and model:
It has a few double columns, a couple of datetime and char, one json column and one enum column.
They are defined the same in the model.
1) Please check the isolation level on database
2) In general the Transactions may be what you need, if the issue with isolation level appears, try to select different isolation level for a transaction
3) cluster mode may result in such issues
So, the .then(... block is executed after the update promise is resolved. And it does not have influence on the update query.
return sequelize.transaction(function (t) {
// chain all your queries here. make sure you return them.
return yourModel.update(updates,{where: { 'id': id } },
{transaction: t}).then(function (entries) {
// your logic with your entries.
});
}).then(function (result) {
// Transaction has been committed
cb(null,result);
console.log('transaction commited');
}).catch(function (err) {
// Transaction has been rolled back
cb(err,null);
console.log('Transaction rolled back');
});
And if you are curious on what was happening when you add .then(delay(100))... statement use catch block because when you find the entries diffrenet from what you have expected it is because the query has already failed to update.

how to catch ethereum contract exception?

This is my simple contract
contract Test {
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
/* Initializes contract with initial supply tokens to the creator of the contract */
function Test(
uint256 initialSupply
) {
balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
}
/* Send coins */
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
balanceOf[msg.sender] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
}
function gettokenBalance(address to)constant returns (uint256){
return balanceOf[to];
}
}
When i am transferring tokens more than intial supply to another account the function transfer should throws exception.
How can i handle this exception and get to know transaction cannot complete.I am using web3j and calling function transfer like
Test test = Test.load(contractObj.getContractAddress(), web3j, credentials, gasprice,gaslimit);
TransactionReceipt balanceOf = test.transfer(new Address(address), transferBalance).get();
How can i handle this exception and get to know transaction cannot
complete
There is a single exception (a throw without arguments) in Solidity, which is "out of gas". So your "faulty" transaction is completed, however it ran out of gas. If you know the transaction hash, you can check gasLimit and gasUsed. If they are equal, your transaction has probably* ran out of gas. See more information here.
* given that you supply more than enough gas that a "correct" transaction requires.
I have never used web3js but you can try using try-catch:
try{
Test test = Test.load(contractObj.getContractAddress(), web3j, credentials, gasprice,gaslimit);
TransactionReceipt balanceOf = test.transfer(new Address(address), transferBalance).get();
} catch (Exception e){
// log you exception
}

Categories

Resources