Hi @LucaAsga,
Welcome to the community ![]()
For a contract to be a GSN recipient it needs three things, whilst OpenZeppelin Contracts (and OpenZeppelin Contracts Ethereum Package) handle msg.sender and msg.data differently, contracts we write need to do all three.
https://docs.openzeppelin.com/contracts/2.x/gsn-strategies
A GSN recipient contract needs the following to work:
- It needs to have funds deposited on its RelayHub.
- It needs to handle
msg.senderandmsg.datadifferently.- It needs to decide how to approve and reject relayed calls.
The reason for the compilation error is that for upgradeable contracts we need to use @openzeppelin/contracts-ethereum-package.
https://docs.openzeppelin.com/sdk/2.5/linking
NOTE: Make sure you install@openzeppelin/contracts-ethereum-packageand not the vanilla@openzeppelin/contracts. The latter is set up for general usage, while@openzeppelin/contracts-ethereum-packageis tailored for being used with the OpenZeppelin SDK. This means that its contracts are already set up to be upgradeable.
I recently created an issue to add a warning to users: OpenZeppelin/openzeppelin-sdk#1297 .
There is also a plan to remove this requirement to use the Contracts Ethereum Package version: Planning the demise of OpenZeppelin Contracts' evil twin.
Also with upgradeable contracts we need to use initializers rather than constructors.
https://docs.openzeppelin.com/sdk/2.5/writing-contracts
You can use your Solidity contracts in the OpenZeppelin SDK without any modifications, except for their constructors. Due to a requirement of the proxy-based upgradeability system, no constructors can be used in upgradeable contracts.
Simple721Token (GSN enabled)
The following ERC721 is GSN enabled and accepts all relayed calls.
For a production dapp we would want to decide which calls to accept so should implement a GSN Strategy (see https://docs.openzeppelin.com/contracts/2.x/gsn-strategies)
pragma solidity ^0.5.5;
import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/ERC721Mintable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/GSN/GSNRecipient.sol";
contract Simple721Token is Initializable, ERC721Full, ERC721Mintable, GSNRecipient {
function initialize(address sender) public initializer {
ERC721.initialize();
ERC721Metadata.initialize("Token", "TKN");
ERC721Enumerable.initialize();
ERC721Mintable.initialize(sender);
}
function acceptRelayedCall(
address relay,
address from,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata approvalData,
uint256 maxPossibleCharge
) external view returns (uint256, bytes memory) {
return _approveRelayedCall();
}
function _preRelayedCall(bytes memory context) internal returns (bytes32) {
}
function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal {
}
}
Please ask all the questions that you need.