How to use hex function with abi.encodeWithSignature() - ethereum

Solidity version used: 0.4.24
Can this:
if(!addr.call(abi.encodeWithSignature("SomeFunction(uint256,uint256)",100,22))){
revert();
}
Be converted to this :
if(!addr.call(abi.encodeWithSignature("0xdchbe039000000000000002"))){
revert();
}
hex ?

Related

line 88; ParserError: expected ';' but got reserved keyword 'in' for (address user in orderBook[to ^^

`function to calculate the current price of a listed token based on the available orders in the order book
function getPrice(address token) public view returns (uint256) {
require(tokens\[token\], "Token is not listed");
uint256 totalAmount = 0;
uint256 totalPrice = 0;
for (address user in orderBook\[token\]) {
totalAmount = totalAmount.add(orderBook\[token\]\[user\]);
totalPrice = totalPrice.add(orderPrices\[token\]\[user\].mul(orderBook\[token\]\[user\]));
}
return totalPrice.div(totalAmount);
}`
6th line down, line 88 throwing this error line 88;
ParserError: expected ';' but got reserved keyword 'in' 88:19
88 | for (address user in orderBook[token] {
^^
haven't tried anything to fix it cause im not great at solidity
In solidity you can't loop over an array like this:
for (element in array) {
...
}
but you have to do it like this:
for (uint256 i=0; i < array.length; i++) {
// element = array[i];
...
}

Why can't I get bool to work properly in Solidity Assembly function?

I'm making an IsPrime function using Solidity Assembly code.
The function takes a number as parameter and returns true for prime, and false otherwise.
I've gotten my function to work, but I had to do a workaround outside of the assembly code.
See the code below:
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.4.26;
contract PrimeNumber{
function isPrimeNumber(uint num1) public view returns(bool) {
uint result = 20; // bool result = true;
assembly{
for {let i := 2} lt(i, num1) {i := add(i, 1)}{
if eq(mod(num1, i), 0) {result := 10} // result := false
}
}
if(result == 10){
return false;
}
return true; // return result;
}
}
So the function works, but I can't for the life of me, get it to work properly using only BOOL and assembly.
I had to add a normal if/else statement after the assembly because I could only get the result to work properly as a UINT type.
I've tried switch statements but I get the error "true and false are not valid literals"
See comments for what I want to do.
Solidity assembly is not able to work with true and false literals until Solidity version 0.6. I haven't found any info about this in the docs - only validated by trying different versions.
You can bypass this limitation by using false-like value, e.g. 0.
pragma solidity ^0.4.26;
contract PrimeNumber{
function isPrimeNumber(uint num1) public view returns(bool) {
bool result = true;
assembly{
for {let i := 2} lt(i, num1) {i := add(i, 1)}{
if eq(mod(num1, i), 0) {
result := 0
}
}
}
return result;
}
}
Note: Latest version of Solidity (November 2022) is 0.8.17. So if your use case allows it, I'd recommend you to use the latest version as it contains bug fixes and security improvements.

Is there a way to retrieve JSON on Solidity on ERC-721?

I'm practicing on an ERC_721 contract and would like to know if there's a way to store JSON data directly on the contract, take a look at my approach and give your thoughts:
The variation1.json file uploaded to IPFS:
{
"attributes": [
{
"trait_type": "Rank",
"value": "1"
}
],
"description": "A simple NFT",
"image": "Qmdasifhw89rv92enfkq128re3",
"name": "NFT#1"
}
Then I would use an object like the one below to go with the contract that references the file to the urlOfTokenURI
[
{
"file": "variation1.json", "urlOfTokenURI": https://gateway.pinata.cloud/ipfs/Qmdasifhw89rv92enfkqeqe23f"
},
{
"file": "variation2.json", "urlOfTokenURI": "https://gateway.pinata.cloud/ipfs/Qmgvfrg34vt4u785ygbmasdsa"
},
...
]
Then get a random number, retrieve a random urlOfTokenURI and mint the token to the desired address, excluding that token from the list of available tokens:
function mintNFT(address recipient, string memory tokenURI)
public onlyOwner
returns (uint256)
{
_tokenIds.increment();
//retrieve object, get random number and mint with the urlOfTokenURI
//from random number index
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
What's missing here for this to work?
Can someone guide me how to proceed or have a suggestion for another approach? I'm kind of lost.
Don't understand how to mint a random NFT and instantly revealing it to the user.
Sorry in advance if it's a stupid question. I'm learning, btw.
Appreciate the help!
If you need a real random number fn, you need to look for oracle service (e.g. Chainlink)
Yes, it is possible to generate an uri without publishing to IPFS. You can generate a base64 data uri instead. Check out Example from wizard and dragon game and their contract
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/utils/Strings.sol";
...
using Strings for uint256;
using Base64 for bytes;
...
function tokenURI(uint256 id) public view returns (string memory) {
string memory metadata = string(abi.encodePacked(
"{\"name\": \"NFT#",
id.toString(),
"\", \"description\": \"A simple NFT\", \"attributes\":",
"[{\"key\":\"trait_type\",\"value\":\"1\"}]",
"}"
));
return string(abi.encodePacked(
"data:application/json;base64,",
bytes(metadata).base64()
));
}
Base64 lib
pragma solidity ^0.8.0;
library Base64 {
string internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function base64(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return "";
// load the table into memory
string memory table = TABLE;
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((data.length + 2) / 3);
// add some extra buffer at the end required for the writing
string memory result = new string(encodedLen + 32);
assembly {
// set the actual output length
mstore(result, encodedLen)
// prepare the lookup table
let tablePtr := add(table, 1)
// input ptr
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
// result ptr, jump over length
let resultPtr := add(result, 32)
// run over the input, 3 bytes at a time
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 3)
// read 3 bytes
let input := mload(dataPtr)
// write 4 characters
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F)))))
resultPtr := add(resultPtr, 1)
}
// padding with '='
switch mod(mload(data), 3)
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
}
return result;
}
}

Stm Cube IDE ERROR : Comparison error for function

I am experimenting with the STM32f407vg board through the STMBUBEIDE program.
First of all, I prepare my own library file and make the settings in the interrupt section.
What if the reason I can't get rid of this error?
First of all, I have a griodriver.c file for my src file. And my definition in it:
uint8_t portcode = GPIO_BASE_ADDR_TO_CODE (pGPIOHandle-> pGPIOx);
Then I write my function so that this comes back.
uint16_t GPIO_BASE_ADDR_TO_CODE(*x)
{
if(x==GPIOA) { return 0; }
else if(x==GPIOB) { return 1; }
else if(x==GPIOC) { return 2; }
else if(x==GPIOD) { return 3; }
else if(x==GPIOE) { return 4; }
else if(x==GPIOF) { return 5; }
else if(x==GPIOG) { return 6; }
}
If I remove the pointer inside the loop, I get a comparison between pointer and interger error.
Whenever I compile I get an error.
My error says this for the function:
This is warnings error.
Description Resource Path Location Type
implicit declaration of function 'GPIO_BASE_ADDR_TO_CODE'; did you mean 'GPIOJ_BASEADDR'?
[- Wimplicit-function-declaration] stm32f407xx_gpio_driver.c /stm32f407xx/drivers/Src
line 253 C/C++ Problem
But there are 2 other errors I get as ERROR.
enter image description here
enter image description here
First:
1. ERROR: Description Resource Path Location Type
make: *** [drivers/Src/subdir.mk:18: drivers/Src/stm32f407xx_gpio_driver.o]
Error 1 stm32f407xx C/C++ Problem
SEcond:
Description Resource Path Location Type
expected declaration specifiers or '...' before '*' token stm32f407xx_gpio_driver.c
/stm32f407xx/drivers/Src line 168 C/C++ Problem
Error Screen:
enter image description here
When I change this part like a below,
uint16_t GPIO_BASE_ADDR_TO_CODE(uint8_t x)
{
if( x==GPIOA) { return 0; }
else if(x==GPIOB) { return 1; }
else if(x==GPIOC) { return 2; }
else if(x==GPIOD) { return 3; }
else if(x==GPIOE) { return 4; }
else if(x==GPIOF) { return 5; }
else if(x==GPIOG) { return 6; }
return 0;
}
My errors change like that :
enter image description here
Instead of calling it in a function, I defined it as #define for
GPIO_BASEADDR_TO_CODE
Also removed if else condition. I used a C third conditional.
Now is no errors after 3 days later:))
You can see it below pictures what I did.
#define GPIO_BASEADDR_TO_CODE(x) ((x == GPIOA)?0 :\
(x == GPIOB)?1 :\
(x == GPIOA)? :\
(x == GPIOA)?3 :\
(x == GPIOA)?4 :\
(x == GPIOA)?5 :\
(x == GPIOA)?6 :\
(x == GPIOA)?7 :0 )
enter image description here

How to makle a video link appear within a HTML code on Arduino w/Ethernet Shield?

I'm pretty much a novice in arduino code and I'm having trouble with the following code. When I compile it with arduino 0022 there are no errors. If I access the Ethernet shield I see the HTML page fine. The troubles come with that the link to the video I want to post in the code. I'm able to see the frame but the link doesn't ever come up. within that frame all I see is the HTML page that has been created. Is there a chance that there's an error in the code or HTML formatting? Is there a specific Library I need to use? thanks in advance for the help!
#include <SPI.h>
#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
#include <Udp.h>
#include <Servo.h>
char Link[]= "http://www.anywebsite.com"; //video link
Servo tilt;
Servo pan;
int panpos = 90;
int tiltpos = 90;
byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; //physical mac address
byte ip[] = { 192, 128, 13, 169 }; // ip in lan
byte gateway[] = { 192, 128, 13,1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
Server server(80); //server port
String readString = String(30); //string for fetching data from address
void setup(){
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
tilt.attach(3);
pan.attach(9);
tilt.write(90);
pan.write(90);
}
void loop(){
// Create a client connection
Client client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100)
{
//store characters to string
readString += c;
}
Serial.print(c);
if (c == '\n') {
if (readString.indexOf("?") <0)
{
//do nothing
}
else
{
if(readString.indexOf("UP=UP") >0)
{
movetiltupstep();
}
else if(readString.indexOf("DN=DN") >0)
{
movetiltdownstep();
}
else if(readString.indexOf("LT=LT") >0)
{
movepanleftstep();
}
else if(readString.indexOf("RT=RT") >0)
{
movepanrightstep();
}
else if(readString.indexOf("CN=CN") >0)
{
center();
}
}
// now output HTML data starting with standard header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//set background to green
client.print("<body style=background-color:blue>");
client.println("<hr />");
client.println("<center>");
client.println("<h1>Camera control</h1>");
client.println("<form method=get name=SERVO>");
client.println("<input type=submit value=UP name=UP style=\"width:100px\"><br>");
client.println("<input type=submit value=LT name=LT style=\"width:100px\"><input type=submit value=CN name=CN style=\"width:100px\"><input type=submit value=RT name=RT style=\"width:100px\"><br>");
client.println("<input type=submit value=DN name=DN style=\"width:100px\">");
client.println("<hr />");
client.println("<iframe width= 640 height= 360 src= Link[]frameborder= 0 allowfullscreen></iframe>");
client.println("</form>");
client.println("</center>");
client.println("</body></html>");
//clearing string for next read
readString="";
//stopping client
client.stop();
}
}
}
}
}
void movetiltupstep(){
tiltpos = tilt.read();
Serial.println(tiltpos);
if (tiltpos >= 66)
{
tilt.write(tiltpos - 2);
}
}
void movetiltdownstep(){
tiltpos = tilt.read();
Serial.println(tiltpos);
if (tiltpos <= 116)
{
tilt.write(tiltpos + 2);
}
}
void movepanleftstep(){
panpos = pan.read();
Serial.println(panpos);
if (panpos >= 4)
{
pan.write(panpos - 4);
}
}
void movepanrightstep(){
panpos = pan.read();
Serial.println(panpos);
if (panpos <= 176)
{
pan.write(panpos + 4);
}
}
void center(){
panpos = pan.read();
tiltpos = tilt.read();
Serial.println(panpos);
if (panpos < 90)
{
for(int i = panpos; i <= 90; i++) {
pan.write(i);
}
}
else if (panpos > 90)
{
for(int i = panpos; i >= 90; i--) {
pan.write(i);
}
}
if (tiltpos < 90)
{
for(int i = tiltpos; i <= 90; i++) {
tilt.write(i);
}
}
else if (tiltpos > 90)
{
for(int i = tiltpos; i >= 90; i--) {
tilt.write(i);
}
}
}
Yes, actually, your code cannot work. Let's put appart the wrong formatting of the line ("Link[]" which is concatenated to "frameborder"), the page that should start with <html>, that you are lucky to be in a very specific case where the Content-Length header is not required and so on, and let's focus on what you tried to do.
You tried to do what is called a variable interpolation: you assumed that the variable name "Link[]" in the string will be replaced by another string. It is something that does not exist in C or C++.
There are several way to do what you want (you can take a look at the String class which exists since Arduino-019 http://arduino.cc/en/Reference/StringObject and what is called concatenation http://arduino.cc/en/Reference/StringConcat).
In your case, you can simply do that (not tested, but should explain the trick):
client.print("<iframe width=640 height=360 src=");
client.print(Link); // Link is not between quotes!
client.println(" frameborder=0 allowfullscreen></iframe>");
It is less beautiful than what you wanted to do, but it is enough for what you need.