i am pretty new for this area but I wanna create a dapp with auction function. is there any help how I can start that ? I start to create NFT marketplace but I am stuck now with this level, I can not get implementation from my smart contract to javascript.
this is my contract
pragma solidity >=0.7.0 <0.9.0;
contract SimpleAuction{
address payable public beneficiary;
uint public auctionEndTime;
address public highestBidder;
uint public highestBid;
mapping(address => uint) public pendingReturns;
bool ended = false;
event HighestBidIncrease(address bidder, uint amount);
event AuctionEnded(address winner, uint amount);
constructor(uint _biddingTime, address payable _beneficiary){
beneficiary = _beneficiary;
auctionEndTime = block.timestamp + _biddingTime;
}
function bid() public payable{
if (block.timestamp > auctionEndTime){
revert("The auction has already ended");
}
if (msg.value <= highestBid){
revert("There is alreay a higher or equal bid");
}
if (highestBid != 0){
pendingReturns[highestBidder] += highestBid;
}
highestBidder = msg.sender;
highestBid = msg.value;
emit HighestBidIncrease(msg.sender, msg.value);
}
function withdraw() public returns (bool){
uint amount = pendingReturns[msg.sender];
if(amount > 0){
pendingReturns[msg.sender] = 0;
if(!payable(msg.sender).send(amount)){
pendingReturns[msg.sender] = amount;
return false;
}
}
return true;
}
function auctionEnd() public{
if (block.timestamp < auctionEndTime){
revert ("The auction has not ended yet");
}
if (ended){
revert("the function auctionEnded has already been called");
}
ended = true;
emit AuctionEnded(highestBidder, highestBid);
beneficiary.transfer(highestBid);
}
}
i see that you took this code from the moralis auction tutorial,
1- this code is not useful for your marketplace as it is right now since this smart contracts starts the auction when the contract is DEPLOYED (which means when u run truffle migrate)
2- your smart contract needs 2 parameters to be deployed anyway which are the beneficiary address and the time of the auction, have you been able to deploy it correctly?? if not you have to add to your migrations this code :
const Auction = artifacts.require("Auction");
module.exports = function (deployer) {
deployer.deploy(Auction,"120","0xF17A576C88EE43D30b67Eb412e2D588e2866102F");
};
where the 120 is the time in seconds and the address is the beneficiary address, ofc this is hardcoded for exemple purposes, you can input the values u like from certain variables
3- this smart contract is good for learning the logic of an auction but is useless for your actual project
Related
i got stucked in it and i don't understand where the error is...
Is a Lottery Project and the problem comes in placeABid function in lottery.sol contract.
Below i attached my code:
LotteryToken.sol
//SPDX-License-Identifier: MIT
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
pragma solidity ^0.8.4;
contract LotteryToken is Ownable, ERC20{
mapping(address=>uint)private _balances;
constructor(string memory name, string memory symbol, uint totalSupply)ERC20(name, symbol){
_mint(msg.sender, totalSupply);
_balances[msg.sender] = totalSupply;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
address owner = owner();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function _transfer(
address _from,
address _to,
uint _amount
)internal virtual override{
_balances[_from] -= _amount;
_balances[_to] += _amount;
super._transfer(_from, _to, _amount);
}
function balanceOf(address account)public view virtual override returns(uint){
return _balances[account];
}
}
Lottery.sol
//SPDX-License-Identifier: MIT
import "#openzeppelin/contracts/access/Ownable.sol";
import "./LotteryToken.sol";
import "./LotteryInfo.sol";
pragma solidity ^0.8.4;
contract Lottery is Ownable{
LotteryInfo private lotteryInfo;
LotteryToken private lotteryToken;
event BidCorrect(address bidder, uint tokenId, uint defaultBid);
constructor(){
}
function initLotteryTokenContract(address _lotteryTokenContract)public onlyOwner{
lotteryToken = LotteryToken(_lotteryTokenContract);
lotteryToken.increaseAllowance(address(this), lotteryToken.balanceOf(lotteryToken.owner()));
}
function initLotteryInfoContract(address _lotteryInfoContract)public onlyOwner{
lotteryInfo = LotteryInfo(_lotteryInfoContract);
}
function setItemToWin(
string memory _name,
uint _defaultBid,
uint _endingTimeLottery
)public onlyOwner{
require(_endingTimeLottery > block.timestamp, "Cannot set a date in the Past!");
lotteryInfo.setItemToWin(_name, _defaultBid, _endingTimeLottery);
}
function buyTokens(uint _quantity)external payable{
uint singleTokenPrice = 0.02 ether;
uint finalPrice = singleTokenPrice * _quantity;
require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Buy Tokens!");
require(msg.value == finalPrice, "Please set the right price!");
payable(owner()).transfer(msg.value);
address lotterytokenOwner = lotteryToken.owner();
lotteryToken.transferFrom(lotterytokenOwner, msg.sender, _quantity);
}
function placeABid(uint _tokenIds)external{
require(block.timestamp < lotteryInfo.getEndingTimeLottery(_tokenIds), "Lottery is closed!");
require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Place A Bid!");
uint requiredTokenAmounts = lotteryInfo.getDefaultItemBid(_tokenIds);
require(lotteryToken.balanceOf(msg.sender) >= requiredTokenAmounts, "No Necessary Funds To Partecipate!");
address lotteryTokenOwner = lotteryToken.owner();
lotteryToken.transferFrom(msg.sender, lotteryTokenOwner, requiredTokenAmounts);
lotteryInfo.updateBid(_tokenIds, requiredTokenAmounts);
lotteryInfo.updateAddress(_tokenIds, msg.sender);
emit BidCorrect(msg.sender, _tokenIds, requiredTokenAmounts);
}
There is another contract LotteryInfo but doesn't need to understand the problem.
What i want to do is to place a bid and send back the amount of bid to the lotteryToken.owner() but i receive error revert "ERC20 insufficient allowance".
Can someone explain me why?
Thanks a lot
You have to call "approve" method from the caller of "placeABid" function. He/She has to approve your Lottery contract to spend (calling transferFrom) he/shes ERC20 tokens. Without increasing the allowance (approval) of ERC20, you wont be able to withdraw ERC20 tokens from msg.sender.
You can detaily check ERC20 standart contract from OpenZeppelin library aswell.
First you have to call approve method from the caller of placeABid function. Then person has to approve your Lottery contract to spend (calling transferFrom) the ERC20 tokens. Without increasing the allowance (approval) of ERC20, you wont be able to withdraw ERC20 tokens from msg.sender.
If amount is the maximum uint256, the allowance is not updated on
* transferFrom. This is semantically equivalent to an infinite approval.
* Requirements:
- spender cannot be the zero address.
Here's a reference link
This is the simple contract in which I am allowing user to open an account i.e smart contract acts as a account. I have kept an initial balance limit of 1 ether i.e user is bond to pay 1 ether at the time of opening of the account. Moreover, user has to set the secret key which will used for withdrawing the balance. In withdraw function I am unable to transfer ether back to the user. I am checking the balance of the user and after verifying balance condition. I am sending back the ether to the depositor. Can anyone help me I have commented the line on which I am facing the issue.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract ActualBank{
uint minAccountBalance=1 ether;
address payable owner;
mapping(address => uint256) balance ;
mapping(address => uint256) secretKey;
constructor(){
owner=payable(msg.sender);
}
function openAccount(uint256 _secretKey) payable public returns(uint256) {
require(msg.value >= minAccountBalance,"There must a minimum balance of 1 ether");
balance[msg.sender]+=msg.value;
secretKey[msg.sender]=_secretKey;
return balance[msg.sender];
}
function withDraw(uint256 _secretKey) payable public returns(uint256) {
require(msg.value <= balance[msg.sender],"With drawal value not correct");
require(secretKey[msg.sender] == _secretKey, "Secret key didn't matched");
balance[msg.sender]-=msg.value;
address payable receiver= payable(msg.sender);
receiver.transfer(msg.value); // issue seems to be on this line
return balance[msg.sender];
}
function getAccountBalance() public view returns(uint256){
return balance[msg.sender];
}
}
I think it's a bit strange because Msg.value is the ETH sent to the contract when the user calls the contract, you should want to send the balance on the contract to the user, right? Then you should change this code
receiver.transfer(msg.value); // issue seems to be on this line
to this
receiver.transfer(address(this).balance); // issue seems to be on this line
UPDATE:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract ActualBank{
uint minAccountBalance=1 ether;
address payable owner;
mapping(address => uint256) balance ;
mapping(address => uint256) secretKey;
constructor(){
owner=payable(msg.sender);
}
function openAccount(uint256 _secretKey) payable public returns(uint256) {
require(msg.value >= minAccountBalance,"There must a minimum balance of 1 ether");
balance[msg.sender]+=msg.value;
secretKey[msg.sender]=_secretKey;
return balance[msg.sender];
}
function withDraw(uint256 _secretKey) payable public returns(uint256) {
require(address(this).balance >= balance[msg.sender],"With drawal value not correct");
require(secretKey[msg.sender] == _secretKey, "Secret key didn't matched");
balance[msg.sender] = 0;
address payable receiver= payable(msg.sender);
receiver.transfer(address(this).balance); // issue seems to be on this line
return balance[msg.sender];
}
function getAccountBalance() public view returns(uint256){
return balance[msg.sender];
}
}
I just modified all the code and it should run fine :)
How can I write to the blockchain after an undetermined, time-consuming execution result?
Situation:
Web Client (NextJS): User requests a long running process that can take up to 1 hour to complete. As a result of this transaction, a new contract instance should be written to the blockchain. We can't expect the client to stick around waiting => use a NodeJS or cloud function to delegate the long running task. Metamask on the client will define the contract owner.
Planning to use NextJS to route to a Moralis Cloud Fx to kick off the long running task. The result of this long running task will be digital content to store to the blockchain.
Constraints/Problem:
Can’t have the user wait for the process to complete
Metamask runs on the client
Need Moralis Cloud Fx or NodeJS to have access to the owner to instantiate the contract at an undetermined future point in time.
From: sequencediagram.org
title Long Running Task to Blockchain
actor User
User->UI:User Request
UI->NodeServer: Delegate Slow Tasks
activate NodeServer
NodeServer->RestService: Start slow process
activate RestService
RestService-->NodeServer: Confirmation ID
NodeServer-->UI: Confirmation ID
UI->Blockchain: Create empty contract
RestService->NodeServer: Result = Data for blockchain
deactivate RestService
NodeServer->Blockchain: **Public?** Contract.setRestResult(Result)
deactivate NodeServer
Here is how I was planning to approach setting up the contract that would straddle the client and server.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract EncryptionNFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private tokenCounter;
uint256 public fee_wei;
bool public isLocked; // has a user paid to access the resource?
string private confirmationId; // long temporary password
string private sensitiveData; // data produced by long running process
address public encryptionService; // service responsible for producing the sensitive data
address public licensor; // licensed process
uint256 public tokenID; // distinct contract id
bool private isMutexed = false; // Reentrancy guard
bool private isSensitiveDataSet = false; // Asserts can only be set 1 time
event unlockPaid(address receiver, uint256 amount);
event withdrawlMade(address receiver, uint256 amount);
constructor(string memory name, uint256 _fee_gwei, string memory _confirmationId, address _encryption_service, address _licensor)
ERC721(name, "DataX")
{
fee_wei = _fee_gwei * 1000000000; // assert numbers are in WEI
isLocked = true; // lock contract by default since data not available => owner shouldn't have to pay unless successful
confirmationId = _confirmationId; // assign temporary password
encryptionService = _encryption_service; // assign addresses for payments
licensor = _licensor; // assign addresses for payments
tokenID = tokenCounter.current(); // Set/Mint with distinct token id
_safeMint(msg.sender, tokenID);
tokenCounter.increment();
}
function unlock() public payable {
require(isLocked == true, "Contract already unlocked.");
require(msg.value >= fee_wei, "Not enough WEI to unlock NFT.");
require(isMutexed == false, "Reentrant call detected!");
isMutexed = true;
// DO PAYMENTS
uint256 rcv_payment = msg.value;
uint256 licensor_cut = rcv_payment / 10;
uint256 encryptor_cut = rcv_payment - licensor_cut;
(bool is_encryptor_success, ) = payable(encryptionService).call{value: encryptor_cut}("");
require(is_encryptor_success, "Encryptor transfer failed.");
emit unlockPaid(encryptionService, encryptor_cut);
(bool is_licensor_success, ) = payable(licensor).call{value: licensor_cut}("");
require(is_licensor_success, "Licensor transfer failed.");
emit unlockPaid(licensor, licensor_cut);
isLocked = false;
isMutexed = false;
}
function withdraw() public payable {
require(msg.sender == ownerOf(tokenID), "Only owner may withdraw.");
require(isLocked == false, "Contract must be unlocked.");
require(isMutexed == false, "Reentrant call detected!");
isMutexed = true;
// DO PAYMENTS
uint256 rcv_payment = msg.value;
uint256 nft_service_cut = rcv_payment / 10;
uint256 licensor_cut = nft_service_cut / 10;
uint256 encryptor_cut = rcv_payment - licensor_cut;
uint256 nft_owner_cut = rcv_payment - nft_service_cut;
(bool is_encryptor_success, ) = payable(encryptionService).call{value: encryptor_cut}("");
require(is_encryptor_success, "Encryptor transfer failed.");
emit withdrawlMade(encryptionService, encryptor_cut);
(bool is_licensor_success, ) = payable(licensor).call{value: licensor_cut}("");
require(is_licensor_success, "Licensor transfer failed.");
emit withdrawlMade(licensor, licensor_cut);
(bool is_nft_owner_success, ) = payable(ownerOf(tokenID)).call{value: nft_owner_cut}("");
require(is_nft_owner_success, "NFT Owner transfer failed.");
emit withdrawlMade(ownerOf(tokenID), nft_owner_cut);
isMutexed = false;
}
function setTokenURI(string memory _tokenURI) public {
require(_isApprovedOrOwner(_msgSender(), tokenID), "ERC721: transfer caller is not owner nor approved.");
_setTokenURI(tokenID, _tokenURI);
}
// Here's how I was planning to allow a server-side process to set the data on REST service completion (slow task)
function setSensitiveData(string memory _confirmationId, string memory _sensitiveData) public {
require(keccak256(bytes(_confirmationId)) == keccak256(bytes(confirmationId)), "Confirmation ID does not match.");
require(isSensitiveDataSet == false, "Sensitive Data has already been set");
sensitiveData = _sensitiveData;
isSensitiveDataSet = true;
}
function getSensitiveData() public view returns (string memory){
require(isSensitiveDataSet == true, "Sensitive Data must be set first.");
require(msg.sender == encryptionService, "Only encryption service accessible.");
return sensitiveData;
}
}
Edit I just found Moralis has a session that appears to allow server side access as a corresponding user. Has anyone played with this before? Would it work for this use case?
Moralis Docs
the command "truffle migrate" works properly (no errors) but only migrates "Migrations.sol". It does not even attempt to migrate with 2_deploy_contracts.js
1_initial_migration.js :
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
Migrations.sol:
enter code herepragma solidity ^0.4.25;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function Migration() public {
owner = msg.sender;
}
function setCompleted(uint completed) restricted public{
last_completed_migration = completed;
}
function upgrade(address new_address) restricted public{
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
2_deploy_contracts.js:
var Election = artifacts.require("./Election.sol");
module.exports = function(deployer) {
deployer.deploy(Election);
};
Election.sol:
pragma solidity ^0.4.25;
contract Election {
// Store candidate
// Read candidate
string public candidate;
// Constructor
// Our constructor will be run when the contract gets deployed, so must be public
constructor() public{
candidate = "Candidate 1";
}
}
Solution: I deleted my project folder and rebuilt it. This fixed it. Not sure exactly what the issue was.
I want to create my own Eth token, using Ethereum wallet and the code from this simple tutorial given in the ethereum.org website.
I don't have a programming background, knowing only basic info about JS and need a lot of help.
Custom ETH tokens are used, for example, as ICO to fund tech-based teams. If I understand correctly, when a certain address receives ETH (sent by a person to an ICO), the "contract" made by this ICO sends him back a portion of the custom tokens.
Is this present in the code below?
How can I edit the "ratio" between ETH and the custom token (example: you send 1 ETH and receive 588 c.tokens - ratio 1:588)?
pragma solidity ^0.4.8;
contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract MyToken {
/* Public variables of the token */
string public standard = 'Token 0.1';
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
/* This generates a public event on the blockchain that will notify clients */
event Transfer(address indexed from, address indexed to, uint256 value);
/* This notifies clients about the amount burnt */
event Burn(address indexed from, uint256 value);
/* Initializes contract with initial supply tokens to the creator of the contract */
function MyToken(
uint256 initialSupply,
string tokenName,
uint8 decimalUnits,
string tokenSymbol
) {
balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
totalSupply = initialSupply; // Update total supply
name = tokenName; // Set the name for display purposes
symbol = tokenSymbol; // Set the symbol for display purposes
decimals = decimalUnits; // Amount of decimals for display purposes
}
/* Send coins */
function transfer(address _to, uint256 _value) {
if (_to == 0x0) throw; // Prevent transfer to 0x0 address. Use burn() instead
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
Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
}
/* Allow another contract to spend some tokens in your behalf */
function approve(address _spender, uint256 _value)
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/* Approve and then communicate the approved contract in a single tx */
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
/* A contract attempts to get the coins */
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (_to == 0x0) throw; // Prevent transfer to 0x0 address. Use burn() instead
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
allowance[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
}
function burn(uint256 _value) returns (bool success) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(msg.sender, _value);
return true;
}
function burnFrom(address _from, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(_from, _value);
return true;
}
}
1) get amount of custom token (msg.value/ratioAmount)
2) transfer that amount to the requester
you have to use a payable fallback function in which you should call a function which will be dealing with above two mentioned activities.
Send() will invoke payable fallback function which in turn call your custom function which will be doing the actual work.
Check fallback function in solidity documentation.
payable is necessary for send() after DAO incident.