I successfully ran my truffle test with 1 contract passing while two failed for reasons that do not make sense to me right now.
I wrote a smart contract that “complies with ERC721 & ERC4907 standards” (NFT renting) & the two that failed are suppose to:
“should not set UserInfo if not owner.”
”should return the correct UserInfo”
These are the errors that’s occurring:
Contract: RentablePets
✔ should support the ERC721 and ERC4907 standards (151ms)
1) should not set UserInfo if not the owner
Events emitted during test:
---------------------------
IERC721.Transfer(
from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
to: <indexed> 0x789d525ABeEC5574bbedB70aD2ABaac6Ed7513Bb (type: address),
tokenId: <indexed> 1 (type: uint256)
)
---------------------------
2) should return the correct UserInfo
Events emitted during test:
---------------------------
IERC721.Transfer(
from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
to: <indexed> 0x789d525ABeEC5574bbedB70aD2ABaac6Ed7513Bb (type: address),
tokenId: <indexed> 2 (type: uint256)
)
IERC721.Transfer(
from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
to: <indexed> 0x789d525ABeEC5574bbedB70aD2ABaac6Ed7513Bb (type: address),
tokenId: <indexed> 3 (type: uint256)
)
IERC4907.UpdateUser(
tokenId: <indexed> 2 (type: uint256),
user: <indexed> 0x33f1E2280D313ccAAC2Ea7D0cBd4994D1a9B99Da (type: address),
expires: 1660252958 (type: uint64)
)
IERC4907.UpdateUser(
tokenId: <indexed> 3 (type: uint256),
user: <indexed> 0xF862B034cb81e0b0bd75B88A6570D9A477B4111c (type: address),
expires: 4121727755 (type: uint64)
)
---------------------------
1 passing (4s)
2 failing
Contract: RentablePets
should not set UserInfo if not the owner:
Wrong kind of exception received
expected - actual
-ERC721: transfer caller is not approved
+ERC721: transfer caller is not owner nor approved
at expectException (node_modules/#openzeppelin/test-helpers/src/expectRevert.js:20:30)
at expectRevert (node_modules/#openzeppelin/test-helpers/src/expectRevert.js:75:3)
at Context. (test/rentable_pets.js:26:5)
Contract: RentablePets
should return the correct UserInfo:
ReferenceError: unexpiredNFTUser is not defined
at Context. (test/rentable_pets.js:50:18)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
(base) mariamstar1#mariams-MacBook-Pro rentable-NFTs %
Related
I'm new to solidity. I'm currently getting the following error TransferHelper: TRANSFER_FROM_FAILED from the safeTransferFrom function. Can someone tell me why?
What is this line doing?
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x23b872dd, from, to, value)
);
Here's the entire contract:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
/**
* #dev A helper methods for interacting with ERC20 tokens and
sending ETH that do not consistently return true/false.
*/
library TransferHelper {
function safeApprove(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x095ea7b3, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper: APPROVE_FAILED"
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0xa9059cbb, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper: TRANSFER_FAILED"
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x23b872dd, from, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper: TRANSFER_FROM_FAILED"
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, "TransferHelper: ETH_TRANSFER_FAILED");
}
}
Just a note, TransferHelper is the prewritten library, and we shouldn't touch into it. What you should do is see the message like: Transfer From Failed or approved fail and check our ERC20 token code as well as the data submit whether it's valid or not.
1st question:
This problem usually happens when your ERC20 token can't be transfer.
There're several reason for this: un-approval, not enough balance...
2nd question:
abi.encodeWithSelector(0x23b872dd, from, to, value)
This function returns a selector (think of is as a function ref) to the transfer(...) of your ERC20 token. And this is called by token.call( a kind of reflection.
This error is for the following reasons:
if the token has fees on transfer remember to be correctly calling the exchange function that supports transfer fees: https://docs.uniswap.org/protocol/V2/reference/smart-contracts/router-02
note that the token submissions permission is sufficient in the token contract. The same happens with the manipulation of WETH it is necessary to give the necessary permissions in the contract.
I created a simple contract as blow shows. When I deployed it and try to call get function, I found that I couldn't input the correct parameter with bytes4 type. No matter I used 0x01,11,"11"..., it always told that error encoding argument like this.
transact to Test.get errored: Error encoding arguments: Error: invalid arrayify value (argument="value" value="11" code=INVALID_ARGUMENT version=bytes/5.5.0)
transact to Test.get errored: Error encoding arguments: Error: invalid arrayify value (argument="value" value="0x6162" code=INVALID_ARGUMENT version=bytes/5.5.0)
What should I do ?
pragma solidity ^0.4.0;
contract Test {
mapping (bytes8 => string) public map;
function setMapping() public {
map["k1"] = "yes";
}
function get(bytes4 a) public {
}
}
You can enter the bytes in the hex form, undivided. Since bytes4 is a fixed-length array of four bytes, you always need to input exactly 4 bytes (8 hex characters).
0x12345678
12 is the first byte
34 is the second byte
etc...
Note: If you want to input empty bytes, you can use 00 in the location of the empty byte. Example: 0x00340078 (1st and 3rd byte are empty).
I'm new to Rust and Typed languages and am having trouble making a post request using reqwest in Rust. I'm not sure which arguments I should pass in to the Result return type enum.
I'm also not sure if my approach so far is the right on because I get errors when I call .await; after send. Does this function need to be async?
error[E0308]: mismatched types
--> rust/src/lib.rs:41:13
|
41 | Ok(res) => res,
| ^^^^^^^ expected opaque type, found enum `std::result::Result`
|
::: home/.cargo/registry/src/reqwest-0.11.3/src/async_impl/request.rs:416:26
|
416 | pub fn send(self) -> impl Future<Output = Result<Response, crate::Error>> {
| ---------------------------------------------------- the expected opaque type
|
= note: expected opaque type `impl std::future::Future`
found enum `std::result::Result<_, _>`
error[E0308]: mismatched types
--> rust/src/lib.rs:42:13
|
42 | Err(err) => err,
| ^^^^^^^^ expected opaque type, found enum `std::result::Result`
|
::: /home/.cargo/registry/src/reqwest-0.11.3/src/async_impl/request.rs:416:26
|
416 | pub fn send(self) -> impl Future<Output = Result<Response, crate::Error>> {
| ---------------------------------------------------- the expected opaque type
|
= note: expected opaque type `impl std::future::Future`
found enum `std::result::Result<_, _>`
error: aborting due to 2 previous errors
Ultimately, I'm not sure if I'm on the right track with making a POST request using reqwest, but this is what I have:
enum Result<T, E> {
Ok(T),
Err(E),
}
pub async fn make_request(path: &str) -> Result<(), ()>{
let client = reqwest::Client::new();
let request = client.post(format!("http://localhost:8000/{}", path))
.body("tbd")
.send();
match request {
Ok(res) => res,
Err(err) => err,
}
}
Any advice on moving forward would be greatly appreciated.
I'm in the process of writing an NFS V4 client and am debugging the results with Wireshark. I'm unable to read a file.
Through OPEN followed by GETATTR, I've opened the file and confirmed it's the desired file by the matching length (1001 bytes).
I then try to READ a single byte of the file with offset 0 and length 1. The resulting reply returns 0 bytes of data, even though the EOF is false. Repeated calls to the read command yield the same result.
Is there parameters in open or read that I'm missing to actually read the file?
Wireshark Output
Open Call
Operations (count: 5): SEQUENCE, PUTROOTFH, OPEN, GETFH, GETATTR
Opcode: SEQUENCE (53)
Opcode: PUTROOTFH (24)
Opcode: OPEN (18)
seqid: 0x00000000
share_access: OPEN4_SHARE_ACCESS_READ (1)
share_deny: OPEN4_SHARE_DENY_NONE (0)
clientid: 0x13f5c375a578cd7c
owner: <DATA>
Open Type: OPEN4_NOCREATE (0)
Claim Type: CLAIM_NULL (0)
Opcode: GETFH (10)
Opcode: GETATTR (9)
Open Reply
Operations (count: 5)
Opcode: SEQUENCE (53)
Opcode: PUTROOTFH (24)
Opcode: OPEN (18)
Status: NFS4_OK (0)
StateID
[StateID Hash: 0x91a9]
StateID seqid: 1
StateID Other: 13f5c375a578cd7c00000000
[StateID Other hash: 0x5b73]
change_info
Atomic: Yes
changeid (before): 110
changeid (after): 110
result flags: 0x00000004, locktype posix
.... .... .... .... .... .... .... ..0. = confirm: False
.... .... .... .... .... .... .... .1.. = locktype posix: True
.... .... .... .... .... .... .... 0... = preserve unlinked: False
.... .... .... .... .... .... ..0. .... = may notify lock: False
Delegation Type: OPEN_DELEGATE_NONE (0)
Opcode: GETFH (10)
Status: NFS4_OK (0)
Filehandle
length: 128
[hash (CRC-32): 0xc5dcd623]
FileHandle: 2b3e5cee938ee2b6afff448601a384b8ffc30bab28b5e2a4...
Opcode: GETATTR (9)
Status: NFS4_OK (0)
Attr mask: 0x00000010 (Size)
reqd_attr: Size (4)
size: 1001
Read Call
Operations (count: 3): SEQUENCE, PUTFH, READ
Opcode: SEQUENCE (53)
Opcode: PUTFH (22)
FileHandle
length: 128
[hash (CRC-32): 0xc5dcd623]
FileHandle: 2b3e5cee938ee2b6afff448601a384b8ffc30bab28b5e2a4...
Opcode: READ (25)
StateID
[StateID Hash: 0x91a9]
StateID seqid: 1
StateID Other: 13f5c375a578cd7c00000000
[StateID Other hash: 0x5b73]
offset: 0
count: 1
Read Reply
Operations (count: 3)
Opcode: SEQUENCE (53)
Opcode: PUTFH (22)
Status: NFS4_OK (0)
Opcode: READ (25)
Status: NFS4_OK (0)
eof: 0
Read length: 0
Data: <EMPTY>
For anybody who runs into a similar situation, I was able to fix the problem by changing the cachethis flag in the SEQUENCE operation of the READ call from true to false.
struct SEQUENCE4args {
sessionid4 sa_sessionid;
sequenceid4 sa_sequenceid;
slotid4 sa_slotid;
slotid4 sa_highest_slotid;
bool sa_cachethis; // ensure this is false
};
Some of the behavior of the cachethis flag is described in RFC 5661, but the information does not include why this behavior occurred.
One possibility is that Amazon's implementation of the NFS spec has a bug in the behavior with sa_cachethis.
I need to sign a message for submission to a remote service (over a websocket). To do this, I need to structure a private key based on an integer (my user id) and a passphrase (a base64 encoded string)., hashed using SHA224. I'm using golang, and crypto/ecdsa for this with accompanying packages for byte encoding etc.
Here's the documentation I have:
Signatures use an Elliptic Curve Digital Signature Algorithm (ECDSA)
encoded message containing: user ID, Server Nonce, Client Node and
Private key. Private keys are generated hashing your user ID and your
password with SHA224.
Here's my func:
func NewKey(userId int64, pass string) (prKey ecdsa.PrivateKey) {
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, userId)
passArr := []byte(pass)
sha := sha256.New224()
sha.Write(buf.Bytes())
sha.Write(passArr)
sum := sha.Sum(nil)
var in int64
reader := bytes.NewReader(sum)
err := binary.Read(reader, binary.BigEndian, &in)
if err != nil {
log.Fatal(err)
}
prKey.D = big.NewInt(in)
prKey.PublicKey.Curve = elliptic.P224()
return prKey
}
My intent with this func is that it:
Hashes the userId and pass correctly in a []byte using SHA224.
Reads that into an int64 which is then used as the private key
Constructs an instance of ecdsa.PrivateKey and corresponding ecdsa.PublicKey correctly
Returns said key for use in ecdsa.Sign() function calls
I then sign another message which consists of a userId (integer), and two nonces.
Here's how I sign my message:
key := NewKey(userId, pass) // the above func
msg := sha256.New224().Sum([]byte(userId + srNonce + clNonce))
r, s, err := ecdsa.Sign(rand.Reader, &key, msg)
sig := []string{enc(r.String()), enc(s.String())}
Questions:
Is my NewKey func correct?
The r and s components are very large - presumably because I'm using int64. Could this be an issue?
Is the line sha256.New224().Sum([]byte(userId + pass)) "correct" for hasing those two items?
How can I create my private key correctly (assuming it's wrong) and subsequently sign the message?
I'm very new to ECDSA and have basic crypto knowledge in general.
To answer my own questions:
Is my NewKey func correct?
No.
The r and s components are very large - presumably because I'm using int64. Could this be an issue?
They should be large.
Is the line sha256.New224().Sum([]byte(userId + pass)) "correct" for hashing those two items?
It's correct insofar as I'm passing it a []byte.
How can I create my private key correctly (assuming it's wrong) and
subsequently sign the message?
The key requires a big.Int, so using the following should suffice assuming the hash is correct:
key := new(big.Int).SetBytes(sum)