Is there a way to check if msg.sender owns some collection? - solidity

Is there a way to do the following:
function registerCollection(address __collection) public {
require(msg.sender == IERC721(__collection).owner), "Does not own contract");
...[rest of function]...
}
Is there a way, within solidity, to access the owner field of another contract. So I do not mean owns an NFT of another collection, which could be done by calling .ownerOf(tokenId) and comparing to msg.sender. I want to get the actual owner of the contract.

It's possible that a collection has a address public owner, especially if it inherits from Openzeppelin's Ownable library.
So you are able to get it like this:
interface IOwnable {
function owner() external view returns(address)
}
IOwnable(__collection).owner()
Though be aware that if a collection doesn't gave a public owner the call will revert.

Related

Why is a retrieve function introduced here when the contract already provides this?

this is my first post and I am pretty new to programming and working my way through learning solidity with the help of freeCodeCamp on Youtube right now.
At around 1:48:00 in this video (https://www.youtube.com/watch?v=M576WGiDBdQ) the author introduces the retrieve function which basically has the same functionality of the statement in contract, right? When both of them lead to the same result, why would using the retrieve function be necessary in this case? Isn't this function just going to waste space? Or which advantages does it provide? Unfortunately he doesn't explain it and it's confusing me like hell.
Kind regards
contract SimpleStorage {
uint256 favoriteNumber;
function retrieve() public view returns (uint256) {
return favoriteNumber;
}
}
Storage variables default to internal visibility if you don't specify the visibility. So without that function you don't have a public getter for the variable.
You could remove the need for the view function by simply declaring the variable with public visibility:
uint256 public favoriteNumber;

Why do constructors have to have a public and not internal visibility?

Only initializes the contract, and I don't understand why it is not an internal function. With this, is more cheap the cost of the gas insted implementing a public function
API from Solidity :
// This is the constructor which registers the
// creator and the assigned name.
constructor(bytes32 _name) public {
// State variables are accessed via their name
// and not via e.g. `this.owner`. Functions can
// be accessed directly or through `this.f`,
// but the latter provides an external view
// to the function. Especially in the constructor,
// you should not access functions externally,
// because the function does not exist yet.
// See the next section for details.
owner = msg.sender;
// We do an explicit type conversion from `address`
// to `TokenCreator` and assume that the type of
// the calling contract is `TokenCreator`, there is
// no real way to check that.
creator = TokenCreator(msg.sender);
name = _name;
}

Law of Demeter - Data objects

I'm trying to follow the Law Of Demeter ( see http://en.wikipedia.org/wiki/Law_of_Demeter , http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/ ) as I can see the benefits, however I've become a little stuck when it comes to domain objects.
Domain objects do naturally have a chain and sometimes it's necessary to display the information about the entire chain.
For instance, a shopping basket:
Each order contains a user, delivery info and a list of items
Each order item contains a product and quantity
Each product has a name and price.
Each user contains a name and address
The code which displays the order information has to use all the information about the order, users and products.
Surely it's better and more reusable to get this information through the order object e.g. "order.user.address.city" than for some code higher up to do queries for all the objects I listed above then pass them into the code separately?
Any comments/suggestions/tips are welcome!
One problem with using chained references, such as order.user.address.city, is that higher-order dependencies get "baked into" the structure of code outside the class.
Ideally, in cases when you refactor your class, your "forced changes" should be limited to the methods of the class being refactored. When you have multiple chained references in the client code, refactoring drives you to make changes in other places of your code.
Consider an example: suppose that you'd like to replace User with an OrderPlacingParty, an abstraction encapsulating users, companies, and electronic agents that can place an order. This refactoring immediately presents multiple problems:
The User property will be called something else, and it will have a different type
The new property may not have an address that has city in cases when the order is placed by an electronic agent
The human User associated with the order (suppose that your system needs one for legal reasons) may be related to the order indirectly, - for example, by being a designated go-to person in the definition of the OrderPlacingParty.
A solution to these problems would be to pass the order presentation logic everything that it needs directly, rather than having it "understand" the structure of the objects passed in. This way you would be able to localize the changes to the code being refactored, without spreading the changes to other code that is potentially stable.
interface OrderPresenter {
void present(Order order, User user, Address address);
}
interface Address {
...
}
class PhysicalAddress implements Address {
public String getStreetNumber();
public String getCity();
public String getState();
public String getCountry();
}
class ElectronicAddress implements Address {
public URL getUrl();
}
interface OrderPlacingParty {
Address getAddress();
}
interface Order {
OrderPlacingParty getParty();
}
class User implements OrderPlacingParty {
}
class Company implements OrderPlacingParty {
public User getResponsibleUser();
}
class ElectronicAgent implements OrderPlacingParty {
public User getResponsibleUser();
}
I think, when chaining is used to access some property, it is done in two (or at least two) different situation. One is the case that you have mentioned, for example, in your presentation module, you have an Order object and you would like to just display the owner's/user's address, or details like city. In that case, I think it is of not much problem if you do so. Why? Because you are not performing any business logic on the accessed property, which can (potentially) cause tight coupling.
But, things are different if you use such chaining for the purpose of performing some logic on the accessed property. For example, if you have,
String city = order.user.address.city;
...
order.user.address.city = "New York";
This is problematic. Because, this logic is/should more appropriately be performed in a module closer to the target attribute - city. Like, in a place where the Address object is constructed in the first place, or if not that, at least when the User object is constructed (if say User is the entity and address the value type). But, if it goes farther than that, the farther it goes, the more illogical and problematic it becomes. Because there are too many intermediaries are involved between the source and the target.
Thus, according to the the Law of Demeter, if you are performing some logic on the "city" attribute in a class, say OrderAssmebler, which accesses the city attribute in a chain like order.user.address.city, then you should think of moving this logic to a place/module closer to the target.
You're correct and you'll most likely model your value objects something like this
class Order {
User user;
}
class User {
Address shippingAddress;
Address deliveryAddress;
}
class Address {
String city;
...
}
When you start considering how you will persist this data to a database (e.g. ORM) do you start thinking about performance. Think eager vs lazy loading trade offs.
Generally speaking I adhere to the Law of Demeter since it helps to keep changes in a reduced scope, so that a new requirement or a bug fix doesn't spread all over your system. There are other design guidelines that help in this direction, e.g. the ones listed in this article. Having said that, I consider the Law of Demeter (as well as Design Patterns and other similar stuff) as helpful design guidelines that have their trade-offs and that you can break them if you judge it is ok to do so. For example I generally don't test private methods, mainly because it creates fragile tests. However, in some very particular cases I did test an object private method because I considered it to be very important in my app, knowing that that particular test will be subject to changes if the implementation of the object changed. Of course in those cases you have to be extra careful and leave more documentation for other developers explaining why you are doing that. But, in the end, you have to use your good judgement :).
Now, back to the original question. As far as I understand your problem here is writing the (web?) GUI for an object that is the root of a graph of objects that can be accessed through message chains. For that case I would modularize the GUI in a similar way that you created your model, by assigning a view component for each object of your model. As a result you would have classes like OrderView, AddressView, etc that know how to create the HTML for their respective models. You can then compose those views to create your final layout, either by delegating the responsibility to them (e.g. the OrderView creates the AddressView) or by having a Mediator that takes care of composing them and linking them to your model. As an example of the first approach you could have something like this (I'll use PHP for the example, I don't know which language you are using):
class ShoppingBasket
{
protected $orders;
protected $id;
public function getOrders(){...}
public function getId(){...}
}
class Order
{
protected $user;
public function getUser(){...}
}
class User
{
protected $address;
public function getAddress(){...}
}
and then the views:
class ShoppingBasketView
{
protected $basket;
protected $orderViews;
public function __construct($basket)
{
$this->basket = $basket;
$this->orederViews = array();
foreach ($basket->getOrders() as $order)
{
$this->orederViews[] = new OrderView($order);
}
}
public function render()
{
$contents = $this->renderBasketDetails();
$contents .= $this->renderOrders();
return $contents;
}
protected function renderBasketDetails()
{
//Return the HTML representing the basket details
return '<H1>Shopping basket (id=' . $this->basket->getId() .')</H1>';
}
protected function renderOrders()
{
$contents = '<div id="orders">';
foreach ($this->orderViews as $orderView)
{
$contents .= orderViews->render();
}
$contents .= '</div>';
return $contents;
}
}
class OrderView
{
//The same basic pattern; store your domain model object
//and create the related sub-views
public function render()
{
$contents = $this->renderOrderDetails();
$contents .= $this->renderSubViews();
return $contents;
}
protected function renderOrderDetails()
{
//Return the HTML representing the order details
}
protected function renderOrders()
{
//Return the HTML representing the subviews by
//forwarding the render() message
}
}
and in your view.php you would do something like:
$basket = //Get the basket based on the session credentials
$view = new ShoppingBasketView($basket);
echo $view->render();
This approach is based on a component model, where the views are treated as composable components. In this schema you respect the object's boundaries and each view has a single responsibility.
Edit (Added based on the OP comment)
I'll assume that there is no way of organizing the views in subviews and that you need to render the basket id, order date and user name in a single line. As I said in the comment, for that case I would make sure that the "bad" access is performed in a single, well documented place, leaving the view unaware of this.
class MixedView
{
protected $basketId;
protected $orderDate;
protected $userName;
public function __construct($basketId, $orderDate, $userName)
{
//Set internal state
}
public function render()
{
return '<H2>' . $this->userName . "'s basket (" . $this->basketId . ")<H2> " .
'<p>Last order placed on: ' . $this->orderDate. '</p>';
}
}
class ViewBuilder
{
protected $basket;
public function __construct($basket)
{
$this->basket = $basket;
}
public function getView()
{
$basketId = $this->basket->getID();
$orderDate = $this->basket->getLastOrder()->getDate();
$userName = $this->basket->getUser()->getName();
return new MixedView($basketId, $orderDate, $userName);
}
}
If later on you rearrange your domain model and your ShoppingBasket class can't implement the getUser() message anymore then you will have to change a single point in your application, avoid having that change spread all over your system.
HTH
The Law Of Demeter is about calling methods, not accessing properties/fields. I know technically properties are methods, but logically they're meant to be data. So, your example of order.user.address.city seems fine to me.
This article is interesting further reading: http://haacked.com/archive/2009/07/13/law-of-demeter-dot-counting.aspx

Domain Objects and Value Objects - are they equal?

By looking to the example of a Domain Object into Zend Quickstart tutorial, and other examples considering a DAO/VO patterns, they both seem to be very similar.
Can we deduce that to say "Value Object" is the same as to say "Domain Object" ?
If not, can you please clarify the differences between those?
What is the function of one, and what if the function of another ?
I'm asking this because, both are composed by getters and setters and nothing more then that. It seems that, they do the same function...
Update:
So, Zend Framework Quick Tutorial documentation called this, a domain object:
// application/models/Guestbook.php
class Application_Model_Guestbook
{
protected $_comment;
protected $_created;
protected $_email;
protected $_id;
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function __set($name, $value)
{
$method = 'set' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid guestbook property');
}
$this->$method($value);
}
public function __get($name)
{
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid guestbook property');
}
return $this->$method();
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setComment($text)
{
$this->_comment = (string) $text;
return $this;
}
public function getComment()
{
return $this->_comment;
}
public function setEmail($email)
{
$this->_email = (string) $email;
return $this;
}
public function getEmail()
{
return $this->_email;
}
public function setCreated($ts)
{
$this->_created = $ts;
return $this;
}
public function getCreated()
{
return $this->_created;
}
public function setId($id)
{
$this->_id = (int) $id;
return $this;
}
public function getId()
{
return $this->_id;
}
}
1) Strictly speaking, are we in face of a "Anemic Domain Object" ?
2) Is it called "domain object" just because it contains domain logic ?
3) If this is the case, then, those mappers containing methods like findBookByAuthor(); they are also dealing with domain logic right? Could they be considered domain objects as well ?
Thanks a lot
Typically a value object encapsulates something that has a value: currency, dates, temperature, etc. They may contain a value and units, but they're not complex.
A domain object is likely to be more complex (unless it's an Anemic Domain Object, which is a bunch of getters and setters pretending to be a domain object) because it contains domain logic.
For example, you might have an Invoice domain object that contains many Invoice Lines (a line for each Invoice Item), and each Invoice Line might have a Net Amount, a Tax Amount, and an Invoice Item. The Amounts and maybe Invoice Item would typically be Value Objects and be reasonably simple.
The Invoice itself could be complicated with interest rates for late payment, support for an approval process, or support for your accounting system.
The Value Object is simple enough to be reusable across different domains. The Domain Objects model your actual domain and are typically written to model your specific business or domain, including your business logic.
The reason you'll often see little difference between them is that many developers will use a Transaction Script/Data Transfer Object design, but call it a Domain Model. They label their collections of getters and setters "domain objects".
Building on the previous responses, I am of the opinion that they are not the same:
Domain objects can contain business logic. They represent entities in the problem space, their property values may be changed and are identified by a unique ID.
According to the Gang of Four, Value Objects are immutable. Such objects are not identified by any ID, but instead by their value.
They can be the same thing. And in many cases they are. However:
domain objects can perform business logic (according to domain-driven design at least), value objects can't
domain objects have the whole information, while value objects hold only part of the information that is relevant to its consumer.
For example, in case of an Invoice domain object, it will be same as the value object, and then you can use the same class for both - it will have an invoice number, ordered items, total price.
On the other hand, a User domain object will have a password field and email field, which you want to be able to process within your system, but you should never send to other systems. Hence you need a new, value object, that lacks these two fields.

Examples in Test Driven Development By Example by Kent Beck

I'm reading through Test Driven Development: By Example and one of the examples is bugging me. In chapter 3 (Equality for all), the author creates an equals function in the Dollar class to compare two Dollar objects:
public boolean equals(Object object)
{
Dollar dollar= (Dollar) object;
return amount == dollar.amount;
}
Then, in the following chapter (4: Privacy), he makes amount a private member of the dollar class.
private int amount;
and the tests pass. Shouldn't this cause a compiler error in the equals method because while the object can access its own amount member as it is restricted from accessing the other Dollar object's amount member?
//shouldn't dollar.amount be no longer accessable?
return amount == dollar.amount
Am I fundamentally misunderstanding private?
UPDATE
I decided to go back and code along with the book manually and when I got to the next part (chapter 6 - Equality For All, Redux) where they push amount into a parent class and make it protected, I'm getting access problems:
public class Money
{
protected int amount;
}
public class Dollar : Money
{
public Dollar(int amount)
{
this.amount = amount;
}
// override object.Equals
public override bool Equals(object obj)
{
Money dollar = (Money)obj;
//"error CS1540: Cannot access protected member 'Money.amount'
// via a qualifier of type 'Money'; the qualifier must be of
// type 'Dollar' (or derived from it)" on the next line:
return amount == dollar.amount;
}
}
Does this mean that protected IS instance-based in C#?
Yep, you're fundamentally misunderstanding private. Privacy is class-specific, not instance-specific.
Fundamentally misunderstanding private, Dollar can access any Dollar private method if they are the same class.
Modifier private is class-private, not object-private.
In Java, private means class-private. Within the class, you can access that field in all instances of the class.
In Scala there is also an object-private scope which is written private[this]. Also in other respects Scala's scopes are more flexible (see this article for more information).
But in Java there is no object-private scope.
In languages of the C++ family (C++,Java,C#), access control is only at the class level. So private allows access to any instance of that class.
IIRC in Smalltalk privacy behaves as you expect.