Need My Solidity Contract Reviewed, the original code had arguments, but I don't know how to input that in nor what they mean - arguments

How do I add in the arguments and set the baseURI?
It is mainly having issues identifying totalsupply and baseuri.
input the below
name (string): Test MB
symbol (string): TEST
maxNftSupply (uint256): 10000
saleStart (uint256): 1619060439?
Where would I put this, there is also an encoded view after verification on etherscan, is that something I need to add?
contract TestMB is ERC721, Ownable {
using SafeMath for uint256;
string public TEST_PROVENANCE = "";
uint256 public startingIndexBlock;
uint256 public startingIndex;
uint256 public constant testPrice = 80000000000000000; //0.08 ETH
uint public constant maxTestPurchase = 20;
uint256 public MAX_TEST;
bool public saleIsActive = false;
uint256 public REVEAL_TIMESTAMP;
constructor(string memory name, string memory symbol, uint256 maxNftSupply, uint256 saleStart) ERC721(name, symbol) {
MAX_TEST = maxNftSupply;
REVEAL_TIMESTAMP = saleStart + (9900 * 9);
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
msg.sender.transfer(balance);
}
function reserveTest() public onlyOwner {
uint supply = totalSupply();
uint i;
for (i = 0; i < 100; i++) {
_safeMint(msg.sender, supply + i);
}
}
function setRevealTimestamp(uint256 revealTimeStamp) public onlyOwner {
REVEAL_TIMESTAMP = revealTimeStamp;
}
function setProvenanceHash(string memory provenanceHash) public onlyOwner {
TEST_PROVENANCE = provenanceHash;
}
function setBaseURI(string memory baseURI) public onlyOwner {
_setBaseURI(baseURI);
}
function flipSaleState() public onlyOwner {
saleIsActive = !saleIsActive;
}
function mintTest(uint numberOfTokens) public payable {
require(saleIsActive, "Sale must be active to mint Test");
require(numberOfTokens <= maxTestPurchase, "Can only mint 20 tokens at a time");
require(totalSupply().add(numberOfTokens) <= MAX_TEST, "Purchase would exceed max supply of Test");
require(testPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
for(uint i = 0; i < numberOfTokens; i++) {
uint mintIndex = totalSupply();
if (totalSupply() < MAX_TEST) {
_safeMint(msg.sender, mintIndex);
}
}
if (startingIndexBlock == 0 && (totalSupply() == MAX_TEST || block.timestamp >= REVEAL_TIMESTAMP)) {
startingIndexBlock = block.number;
}
}
function setStartingIndex() public {
require(startingIndex == 0, "Starting index is already set");
require(startingIndexBlock != 0, "Starting index block must be set");
startingIndex = uint(blockhash(startingIndexBlock)) % MAX_TEST;
// Just a sanity case in the worst case if this function is called late (EVM only stores last 256 block hashes)
if (block.number.sub(startingIndexBlock) > 255) {
startingIndex = uint(blockhash(block.number - 1)) % MAX_TEST;
}
// Prevent default sequence
if (startingIndex == 0) {
startingIndex = startingIndex.add(1);
}
}
function emergencySetStartingIndexBlock() public onlyOwner {
require(startingIndex == 0, "Starting index is already set");
startingIndexBlock = block.number;
}
}

If you are the deployer of the contract so you will be the contract owner. Then you will be able to call onlyOwner functions.
To set baseURI, you have to call setBaseURI function with parameter of your base url.
You have to verify your contract source code on etherscan to call functions.
If you don't know how to verify your contract code, then you can deploy your contract through Remix and then you will be able to call contract functions.
I hope i got the problem and this is the answer.

Related

Iterable Mapping- how to retreive all the values with For-Loop?

From looking at the code below can anyone show me how you'd write a for loop to get all the values in the mapping? Thanks in advance for the help.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract IterableMapping {
mapping(address => uint) public balances;
mapping(address => bool) public inserted;
address[] public keys;
function set(address _addr, uint _bal) external {
balances[_addr] = _bal;
if (!inserted[_addr]) {
inserted[_addr] = true;
keys.push(_addr);
}
}
function get(uint _index) external view returns (uint) {
address key = keys[_index];
return balances[key];
}
function first() external view returns (uint) {
return balances[keys[0]];
}
function last() external view returns (uint) {
return balances[keys[keys.length - 1]];
}
```
oh i see my mistake now with trying to get the bool values. it would be...
function getAllBools() public view returns (bool[] memory) {
bool[] memory result = new bool[](keys.length);
for (uint i = 0; i < keys.length; i++) {
result[i] = inserted[keys[i]];
}
return result;
}
You can loop through balances by using address as key , hereby you will get All the values in the balances Mapping.
function getAllBalances() public view returns (uint[] memory){
uint[] memory result = new uint[](keys.length);
for (uint i = 0; i < keys.length; i++) {
result[i] = balances[keys[i]];
}
return result;
}
Likewise you can also get values of the inserted mapping

Solidity Payable function throwing error if it has a loop

I have a contract with the following payable function
Contract Constructor
constructor( address payable _NFT_CONTRACT, address payable _TOKEN_CONTRACT) payable {
NFT_CONTRACT = IERC721(_NFT_CONTRACT);
TOKEN_CONTRACT = IERC20(_TOKEN_CONTRACT);
}
Function Stake:
function stake(uint256[] calldata tokenIds, uint256[] calldata powers) external payable {
for (uint i = 0; i <= tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
uint256 power = powers[i];
require(NFT_CONTRACT.ownerOf(tokenId) == msg.sender, "You can only stake your own token");
require(vault[tokenId].tokenId == 0, "You can only stake once");
NFT_CONTRACT.safeTransferFrom(msg.sender, address(this), tokenId);
vault[tokenId] = Stake({
tokenId: tokenId,
timestamp: block.timestamp,
owner: msg.sender,
power: power
});
userStacks[msg.sender].push(tokenId);
hasPaid[tokenId] = 0;
}
}
vault, userStacks, and hasPaid are all structs.
struct Stake {
address owner;
uint256 tokenId;
uint256 timestamp;
uint256 power;
}
mapping(uint256 => Stake) public vault;
mapping(address => uint256[]) public userStacks;
mapping(uint256 => uint256) public hasPaid;
The problem:
Function stake works perfectly fine if I remove the for loop, but, throws this error if I have the loop:
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
I am using solidity ^0.8.0;
I test with arrays such as [1,2], [4,5], for both params.
Thanks.

Springboot- How to pass the score to an entity class

I am trying to create a program that collects the score at the end and assigns it a grade but it is assigning the grade for every score printed. In layman's terms the system should go through each method and deduct points based on whether the condition is met. Its for a website so I would need to display the scores so I need to use an entity class with getters and setters from what I have read. I am quite lost about how to go about this
public class Review {
public static void main(String[] args) { //getWordLength() { // Checking word length. Less than 6 means reviewer can't weigh out positives and negatives
// TODO Auto-generated method stub
int ReviewScore = 30;
String Review = "me I me, pizza Montreal";
String[] words = Review.split("\\s+");
System.out.println("Word Count is: "+words.length);
int wordlength = Integer.valueOf(words.length);
if (wordlength< 6) {
ReviewScore -=4; // deducts 4pts if review less than 6 words
System.out.println("Score is "+ ReviewScore);
}
verbCount( ReviewScore,Review );
}
public static void verbCount (int ReviewScore, String Review) { //Count verbs 'I' or 'me'
for (String s : Review.split ("\\s+") ) { // splits review into separate words
if (s.contains("me" )){ // Checks for 'me' or 'I'
ReviewScore -= 1;
System.out.println("Score is "+ ReviewScore);
// deducts by 2 pts for each time 'I' is mentioned
}
if ( s.contains ("I")) {
ReviewScore -= 1;
System.out.println("Score is "+ ReviewScore); //deducts by 2 pts for each time 'me' is mentioned
}
WordBucket (ReviewScore, s);
}
}
public static void WordBucket ( int ReviewScore, String s) {
for (String word : Analyser.FREQWORDS) {
if(s.contains(word)) {
System.out.println("Score is "+ ReviewScore);
break;
}
else {
ReviewScore -=5;
System.out.println("Score is "+ ReviewScore);
break;
}
}
Grade (ReviewScore) ;
}
public static void Grade (int ReviewScore) {
int Finalscore= ReviewScore;
if (Finalscore >=20 && Finalscore <=25) {
System.out.println ("a");
} else if (Finalscore >=14 && Finalscore <=19) {
System.out.println ("b");
} else if (Finalscore >=7 && Finalscore <=13 ) {
System.out.println ("c");
} else if ( Finalscore <6)
System.out.println ("d");
else {
System.out.println ("an error has occured") ;
}
}
}
I Believe this is the solution for your query. I understand that you want to print/pass the final Score as well as grade to entity class so in this way we can do where
a) instead of passing each and every word to subsequent function, you are passing the String array itself.
b) returning the score value from each functional call so that the corresponding scores can be saved and passed to other function call.
Also try to avoid using system Print out since it is just for printing to console purpose. You need to return the value from each and every call. If you run this program , the output you are going to get is below
Word Count is: 5
Final Score is 18
Final Grade is b
the lines below
int finalScore = verbCount(ReviewScore, words);
String finalGrade = Grade(finalScore);
Can help you pass the finalScore and finalGrade to entity class which needs to consume these values.
Please note I am using the String array ArrayAnlyser here which I believe you are using as an enum as a part of your program.
public class Review {
public static void main(String[] args) {
int ReviewScore = 30;
String Review = "me I me, pizza Montreal";
String[] words = Review.split("\\s+");
System.out.println("Word Count is: " + words.length);
int wordlength = Integer.valueOf(words.length);
if (wordlength < 6) {
ReviewScore -= 4;
}
int finalScore = verbCount(ReviewScore, words);
System.out.println("Final Score is " + finalScore);
String finalGrade = Grade(finalScore);
System.out.println("Final Grade is " + finalGrade);
}
public static int verbCount(int ReviewScore, String[] words) { //Count verbs 'I' or 'me'
for (String s : words) { // splits review into separate words
if (s.contains("me")) { // Checks for 'me' or 'I'
ReviewScore -= 1;
// System.out.println("Score is "+ ReviewScore);
// deducts by 2 pts for each time 'I' is mentioned
}
if (s.contains("I")) {
ReviewScore -= 1;
// System.out.println("Score is "+ ReviewScore); //deducts by 2 pts for each time 'me' is mentioned
}
}
int RevisedScore = WordBucket(ReviewScore, words);
return RevisedScore;
}
public static int WordBucket(int ReviewScore, String[] words) {
String[] ArrayAnlyser = {"me", "I", "pizza", "Montreal"};
boolean flag = false;
for (String word : words) {
flag = false;
for (String analyWord : ArrayAnlyser) {
if (analyWord.contains(word)) {
// System.out.println("Score is "+ ReviewScore);
flag = true;
break;
}
}
if (!flag) {
ReviewScore -= 5;
// System.out.println("Score is "+ ReviewScore);
}
}
return ReviewScore;
// Grade (ReviewScore) ;
}
public static String Grade(int ReviewScore) {
int Finalscore = ReviewScore;
String grade = "";
if (Finalscore >= 20 && Finalscore <= 25) {
// System.out.println ("a");
grade = "a";
} else if (Finalscore >= 14 && Finalscore <= 19) {
grade = "b";
// System.out.println ("b");
} else if (Finalscore >= 7 && Finalscore <= 13) {
grade = "c";
// System.out.println ("c");
} else if (Finalscore < 6) {
grade = "d";
// System.out.println ("d");
} else {
grade = "error occured";
// System.out.println ("an error has occured") ;
}
return grade;
}
}

Chainlink v0.8 API Large Responses

I am following the Large Responses Chainlink tutorial and am receiving an error when trying to call the requestOracleData() function. Everything works fine when using v0.6, but I need to use v0.8 in order to receive large responses.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
/**
* #title MyContract is an example contract which requests data from
* the Chainlink network
* #dev This contract is designed to work on multiple networks, including
* local test networks
*/
contract MyContract is ChainlinkClient, ERC721 {
using Chainlink for Chainlink.Request;
// address constant ORACLE = 0xF405B99ACa8578B9eb989ee2b69D518aaDb90c1F;
// bytes32 constant JOB_ID = bytes32("7c4b968028f74b2eabd7d428f03ba45c");
address constant RINKEBY_ORACLE =
0x3A56aE4a2831C3d3514b5D7Af5578E45eBDb7a40;
bytes32 constant RINKEBY_JOB_ID =
bytes32("187bb80e5ee74a139734cac7475f3c6e");
uint256 constant FEE = 0.1 * 10**18;
bytes32 internal keyHash;
uint256 public fee;
uint256 public tokenCounter;
// bytes public data;
bytes32 public data;
string public image_url;
struct Clip {
string name;
string url;
}
Clip[] public clips;
mapping(bytes32 => string) public requestIdToClipName;
mapping(bytes32 => address) public requestIdToSender;
mapping(bytes32 => string) public requestIdToTokenURI;
event requestedCollectible(bytes32 indexed requestId);
mapping(bytes32 => uint256) public requestToTokenId;
mapping(uint256 => string) public tokenIdToName;
mapping(uint256 => string) public tokenIdToImgUrl;
constructor(address _link) public ERC721("Tests", "TST") {
if (_link == address(0)) {
setPublicChainlinkToken();
} else {
setChainlinkToken(_link);
}
setChainlinkOracle(0x3A56aE4a2831C3d3514b5D7Af5578E45eBDb7a40);
tokenCounter = 0;
}
function getChainlinkToken() public view returns (address) {
return chainlinkTokenAddress();
}
function createRequestTo(
string memory _url,
string memory _path,
string memory clipName
) public returns (bytes32 requestId) {
Chainlink.Request memory req = buildChainlinkRequest(
RINKEBY_JOB_ID,
address(this),
this.fulfill.selector
);
req.add("get", _url);
req.add("path", _path);
requestOracleData(req, FEE);
requestId = sendChainlinkRequestTo(RINKEBY_ORACLE, req, FEE);
requestIdToClipName[requestId] = clipName;
requestIdToSender[requestId] = msg.sender;
emit requestedCollectible(requestId);
return requestId;
}
function fulfill(bytes32 _requestId, bytes32 _data)
public
recordChainlinkFulfillment(_requestId)
{
address nftOwner = requestIdToSender[_requestId];
string memory name = requestIdToClipName[_requestId];
uint256 newItemId = clips.length;
data = _data;
image_url = bytes32ToString(data);
clips.push(Clip(name, image_url));
_safeMint(nftOwner, newItemId);
tokenIdToName[newItemId] = name;
tokenIdToImgUrl[newItemId] = image_url;
}
function getNumberOfClips() public view returns (uint256) {
return clips.length;
}
/**
* #notice Allows the owner to withdraw any LINK balance on the contract
*/
function withdrawLink() public {
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
/**
* #notice Call this method if no response is received within 5 minutes
* #param _requestId The ID that was generated for the request to cancel
* #param _payment The payment specified for the request to cancel
* #param _callbackFunctionId The bytes4 callback function ID specified for
* the request to cancel
* #param _expiration The expiration generated for the request to cancel
*/
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
) public {
cancelChainlinkRequest(
_requestId,
_payment,
_callbackFunctionId,
_expiration
);
}
function bytes32ToString(bytes32 _bytes32)
public
pure
returns (string memory)
{
uint8 i = 0;
while (i < 32 && _bytes32[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
}
Here is the error I am getting:
Running 'scripts/request_data.py::main'...
File "brownie/_cli/run.py", line 49, in main
return_value, frame = run(
File "brownie/project/scripts.py", line 103, in run
return_value = f_locals[method_name](*args, **kwargs)
File "./scripts/request_data.py", line 18, in main
apicall = my_contract.createRequestTo(URL, PATH, "test", {"from": dev})
File "brownie/network/contract.py", line 1693, in __call__
return self.transact(*args)
File "brownie/network/contract.py", line 1566, in transact
return tx["from"].transfer(
File "brownie/network/account.py", line 642, in transfer
receipt, exc = self._make_transaction(
File "brownie/network/account.py", line 725, in _make_transaction
raise VirtualMachineError(e) from None
File "brownie/exceptions.py", line 121, in __init__
raise ValueError(str(exc)) from None
ValueError: Gas estimation failed: 'execution reverted: Must use whitelisted functions'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.
Note: this error doesn't occur when I comment out the requestOracleData() function.
It is due to the fact that the node operator you are using on Rinkeby isn't set up to handle large requests and is most likely using the Oracle.sol code as their oracle contract, which doesn't accept the requestOracleData() method.
You can either switch to Kovan and use the node given in the docs, search for a different but compatible node on market.link, or host your own node on Rinkeby which is compatible with this job.

Lossless hierarchical run length encoding

I want to summarize rather than compress in a similar manner to run length encoding but in a nested sense.
For instance, I want : ABCBCABCBCDEEF to become: (2A(2BC))D(2E)F
I am not concerned that an option is picked between two identical possible nestings E.g.
ABBABBABBABA could be (3ABB)ABA or A(3BBA)BA which are of the same compressed length, despite having different structures.
However I do want the choice to be MOST greedy. For instance:
ABCDABCDCDCDCD would pick (2ABCD)(3CD) - of length six in original symbols which is less than ABCDAB(4CD) which is length 8 in original symbols.
In terms of background I have some repeating patterns that I want to summarize. So that the data is more digestible. I don't want to disrupt the logical order of the data as it is important. but I do want to summarize it , by saying, symbol A times 3 occurrences, followed by symbols XYZ for 20 occurrences etc. and this can be displayed in a nested sense visually.
Welcome ideas.
I'm pretty sure this isn't the best approach, and depending on the length of the patterns, might have a running time and memory usage that won't work, but here's some code.
You can paste the following code into LINQPad and run it, and it should produce the following output:
ABCBCABCBCDEEF = (2A(2BC))D(2E)F
ABBABBABBABA = (3A(2B))ABA
ABCDABCDCDCDCD = (2ABCD)(3CD)
As you can see, the middle example encoded ABB as A(2B) instead of ABB, you would have to make that judgment yourself, if single-symbol sequences like that should be encoded as a repeated symbol or not, or if a specific threshold (like 3 or more) should be used.
Basically, the code runs like this:
For each position in the sequence, try to find the longest match (actually, it doesn't, it takes the first 2+ match it finds, I left the rest as an exercise for you since I have to leave my computer for a few hours now)
It then tries to encode that sequence, the one that repeats, recursively, and spits out a X*seq type of object
If it can't find a repeating sequence, it spits out the single symbol at that location
It then skips what it encoded, and continues from #1
Anyway, here's the code:
void Main()
{
string[] examples = new[]
{
"ABCBCABCBCDEEF",
"ABBABBABBABA",
"ABCDABCDCDCDCD",
};
foreach (string example in examples)
{
StringBuilder sb = new StringBuilder();
foreach (var r in Encode(example))
sb.Append(r.ToString());
Debug.WriteLine(example + " = " + sb.ToString());
}
}
public static IEnumerable<Repeat<T>> Encode<T>(IEnumerable<T> values)
{
return Encode<T>(values, EqualityComparer<T>.Default);
}
public static IEnumerable<Repeat<T>> Encode<T>(IEnumerable<T> values, IEqualityComparer<T> comparer)
{
List<T> sequence = new List<T>(values);
int index = 0;
while (index < sequence.Count)
{
var bestSequence = FindBestSequence<T>(sequence, index, comparer);
if (bestSequence == null || bestSequence.Length < 1)
throw new InvalidOperationException("Unable to find sequence at position " + index);
yield return bestSequence;
index += bestSequence.Length;
}
}
private static Repeat<T> FindBestSequence<T>(IList<T> sequence, int startIndex, IEqualityComparer<T> comparer)
{
int sequenceLength = 1;
while (startIndex + sequenceLength * 2 <= sequence.Count)
{
if (comparer.Equals(sequence[startIndex], sequence[startIndex + sequenceLength]))
{
bool atLeast2Repeats = true;
for (int index = 0; index < sequenceLength; index++)
{
if (!comparer.Equals(sequence[startIndex + index], sequence[startIndex + sequenceLength + index]))
{
atLeast2Repeats = false;
break;
}
}
if (atLeast2Repeats)
{
int count = 2;
while (startIndex + sequenceLength * (count + 1) <= sequence.Count)
{
bool anotherRepeat = true;
for (int index = 0; index < sequenceLength; index++)
{
if (!comparer.Equals(sequence[startIndex + index], sequence[startIndex + sequenceLength * count + index]))
{
anotherRepeat = false;
break;
}
}
if (anotherRepeat)
count++;
else
break;
}
List<T> oneSequence = Enumerable.Range(0, sequenceLength).Select(i => sequence[startIndex + i]).ToList();
var repeatedSequence = Encode<T>(oneSequence, comparer).ToArray();
return new SequenceRepeat<T>(count, repeatedSequence);
}
}
sequenceLength++;
}
// fall back, we could not find anything that repeated at all
return new SingleSymbol<T>(sequence[startIndex]);
}
public abstract class Repeat<T>
{
public int Count { get; private set; }
protected Repeat(int count)
{
Count = count;
}
public abstract int Length
{
get;
}
}
public class SingleSymbol<T> : Repeat<T>
{
public T Value { get; private set; }
public SingleSymbol(T value)
: base(1)
{
Value = value;
}
public override string ToString()
{
return string.Format("{0}", Value);
}
public override int Length
{
get
{
return Count;
}
}
}
public class SequenceRepeat<T> : Repeat<T>
{
public Repeat<T>[] Values { get; private set; }
public SequenceRepeat(int count, Repeat<T>[] values)
: base(count)
{
Values = values;
}
public override string ToString()
{
return string.Format("({0}{1})", Count, string.Join("", Values.Select(v => v.ToString())));
}
public override int Length
{
get
{
int oneLength = 0;
foreach (var value in Values)
oneLength += value.Length;
return Count * oneLength;
}
}
}
public class GroupRepeat<T> : Repeat<T>
{
public Repeat<T> Group { get; private set; }
public GroupRepeat(int count, Repeat<T> group)
: base(count)
{
Group = group;
}
public override string ToString()
{
return string.Format("({0}{1})", Count, Group);
}
public override int Length
{
get
{
return Count * Group.Length;
}
}
}
Looking at the problem theoretically, it seems similar to the problem of finding the smallest context free grammar which generates (only) the string, except in this case the non-terminals can only be used in direct sequence after each other, so e.g.
ABCBCABCBCDEEF
s->ttDuuF
t->Avv
v->BC
u->E
ABABCDABABCD
s->ABtt
t->ABCD
Of course, this depends on how you define "smallest", but if you count terminals on the right side of rules, it should be the same as the "length in original symbols" after doing the nested run-length encoding.
The problem of the smallest grammar is known to be hard, and is a well-studied problem. I don't know how much the "direct sequence" part adds to or subtracts from the complexity.

Resources